Хорошо, поэтому я пытаюсь изучить многопоточность. Я читаю книгу, и я столкнулся с этим примером для синхронизированных блоков кода:
class CallMe {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable {
String msg;
CallMe target;
Thread t;
public Caller(CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread( this );
t.start();
}
public void run() {
synchronized (target) {
target.call(msg);
}
}
}
public class Scrap {
public static void main(String[] args) {
CallMe target = new CallMe();
Caller ob1 = new Caller( target, "Hello");
Caller ob2 = new Caller( target, "Synchronized" );
Caller ob3 = new Caller( target, "World");
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (Exception e) {
System.out.println("Interrupted");
}
}
}
Я получил следующий результат:
[Hello]
[World]
[Synchronized]
Затем, поскольку я сделал несколько учебников в Интернете, я знаю, что это хороший стиль (или ему сказали) создать экземпляр Object
только для блокировки. Итак, я сделал это, и класс Caller
стал:
class Caller implements Runnable {
String msg;
CallMe target;
Thread t;
private Object lock = new Object();
public Caller(CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread( this );
t.start();
}
public void run() {
synchronized (lock) {
target.call(msg);
}
}
}
Я был немного удивлен, когда получил это как результат:
[Synchronized[Hello[World]
]
]
Конечно, это выводится, когда происходит чередование, и это неверно. Мой вопрос, почему это произошло? Я думал, что создание Object
блокировки даст мне те же результаты. Почему он (или почему бы ему) не дал мне такой же результат? Я думал, что создание экземпляра Object
будет хорошим стилем и будет работать одинаково в этом случае, и, честно говоря, я не понимаю, почему это будет другая блокировка на "target" и "lock". Я предполагаю, что я хочу спросить, почему блокировка на одном определенном элементе в этом случае заставляет программу быть правильной и блокировать с другой, делает ее неправильной?
Каждый экземпляр Caller
блокирует другой экземпляр lock
. Я думаю, вам нужно synchronize
с общими экземплярами. Создание lock
в static
члене будет иметь один и тот же экземпляр для всех потоков.
static
чтобы вы могли ими поделиться. Вы можете передать тот же аргумент, если вам нужно.