Исходя из приведенного ниже кода, у меня есть два экземпляра класса A - a1 и a2.И вызов метода foo () для обоих экземпляров отдельно.
В методе foo () есть синхронизированный блок, который заблокирован для вызывающего объекта.Поскольку это блокировка на уровне экземпляра, оба метода должны начать выполняться одновременно, поскольку они вызываются из двух отдельных экземпляров.Но они выполняются последовательно.
Это потому, что оба экземпляра вызываются из одного и того же основного потока?
Изменения в коде: В класс A реализован Runnable, переименован в foo () в run (), ветвь потока t изmain, вызвал a1.run () из основного потока, вызвал a2.run () из потока t.Хотя два экземпляра A - a1 и a2 вызываются из двух потоков - main & thread t, синхронизированный блок (это), похоже, блокируется.
Насколько я понимаю, слово "this" относится квызов экземпляра Runnable, который отличается, и даже потоки отличаются.Таким образом, Thread.sleep не должен блокировать другой поток.Тогда, почему два вызова run не происходят параллельно?
Ожидаемый вывод (должен выполняться параллельно)
main <time> Inside A.run
Thread-0 <time> Inside A.run
Thread-0 <time+4s> Exiting A.run
main <time+5s> Exiting A.run
Фактический вывод (выполняется последовательно)
main <time> Inside A.run
main <time+5s> Exiting A.run
Thread-0 <time+5s> Inside A.run
Thread-0 <time+9s> Exiting A.run
import java.time.*;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
/*A a1 = new A(5000); A a2 = new A(4000);
a1.foo(); a2.foo();*/
A a1 = new A(5000); A a2 = new A(4000);
Thread t = new Thread(a2);
/*a1.run(); t.start();*/
t.start(); a1.run(); // <-- putting t.start() before a1.run() solves the issue
}
}
class A implements Runnable {
public long waitTime;
public A() {}
public A(long timeInMs) {
waitTime = timeInMs;
}
public void run() {
synchronized(this) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
System.out.println(Thread.currentThread().getName() + " " + formatter.format(time) + " Inside A.run");
Thread.sleep(waitTime);
time = LocalDateTime.now();
System.out.println(Thread.currentThread().getName() + " " + formatter.format(time) + " Exiting A.run");
} catch (InterruptedException e) {}
}
}
}