Я изучаю многопоточность в Java. Я немного смущен тем, как потоки обращаются к методам с использованием ключевого слова synchronized, поскольку я нахожу противоречивые руководства о том, как и какие потоки могут получить к ним доступ. Итак, просто чтобы поделиться своими текущими знаниями:
- Каждый объект, который мы создаем, имеет связанный с ним монитор / блокировку
- Каждый раз, когда поток обращается к синхронизированному методу, он должен иметь блокировку объекта / экземпляра, который он пытается вызвать
- Поток может снять sh блокировку с помощью метода wait () в синхронизированном блоке.
- Как только поток вызывает notify / notifyAll, он пробуждает потоки, которые вызывали метод wait ().
Итак, я сделал фиктивную программу, чтобы выделить то, что мне было любопытно, поскольку я получал смешанные ответы в обучающих материалах (если только я этого не сделал) не понимаю правильно) ..
Main:
public class Main {
public static void main(String[] args) throws InterruptedException {
Operation operation = new Operation();
Thread tOne = new Thread(new OperationProcessor(operation));
Thread tTwo = new Thread(new OperationProcessor(operation));
Thread tThree = new Thread(new OperationProcessor(operation));
Thread tFour = new Thread(() -> {
for(int i =0 ; i < 500; i ++){
operation.subtract();
}
});
tOne.start();
tTwo.start();
tThree.start();
tFour.start();
tOne.join();
tTwo.join();
tThree.join();
System.out.println(operation.counter);
}
}
Operation:
public class Operation {
int counter = 0;
public synchronized void add(){
System.out.println(Thread.currentThread().getName() + " reading the value: " + counter);
counter++; //same as counter = counter + 1;
}
public void subtract(){
System.out.println(Thread.currentThread().getName() + " in the subtract method.");
}
}
Operation Processor:
public class OperationProcessor implements Runnable {
private final Operation operation;
public OperationProcessor(Operation operation) {
this.operation = operation;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
operation.add();
}
}
}
What I попытался сделать это проверить, могут ли разные потоки вызывать другие несинхронизированные методы ОДНОВРЕМЕННО, как другие потоки, вызывающие другие синхронизированные методы в том же экземпляре объекта? Например, если Thread1-3 по очереди вызывает метод add () (из-за блокировки), может ли Thread 4 вызывать subtract (), в то время как Thread1-3 выполняет метод add ()? Но не уверен, продемонстрировал ли я это в этом коде ... А также, если оба метода add () и subtract () были синхронизированы, означает ли это, что ТОЛЬКО один поток имеет доступ ко всем синхронизированным методам в объекте? Например, поток A находится в методе add (), поток B НЕ МОЖЕТ вызвать метод subtract ()?