Добрый день, недавно читал Брюса Эккеля, и наткнулся на такую проблему: блок synchronized(Object) блокирует класс обьекта, е не сам обьект. К такому выводу я пришел после выполнения такого кода :
public class Main {
public static void main(String[] args) {
Sync s = new Sync();
new Thread(new Runnable() {
@Override
public void run() {
s.go();
}
}, "First").start();
new Thread(new Runnable() {
@Override
public void run() {
s.go();
}
}, "Second").start();
}
}
class Sync {
private Writer w1, w2;
public Sync() {
w1 = new Writer();
w2 = new Writer();
}
public void go() {
synchronized (w2) {
w1.log(Thread.currentThread().getName() + "...1");
//!Этот блок кода должен выполнятся паралельно во всех потоках, но выполняется последовательно.
w2.log(Thread.currentThread().getName() + "...2");
//Этот должен выполнятся последовательно, и он так и делает.
}
}
}
class Writer {
public void log(Object obj) {
for (int i = 0; i < 5; i++) {
lgn(obj);
try {
TimeUnit.MILLISECONDS.sleep(750);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Почему при блокировки w2, у меня блокируется и w1? Это же разные обьекты?
В книге и во всех источниках говорится про блокировку в synchronized обьекта! Если я что-то не так сделал или чего-то не понимаю, то могли бы вы мне ответить почему и как?
Вывод
First...1
First...1
First...1
First...1
First...1
First...2
First...2
First...2
First...2
First...2
Second...1
Second...1
Second...1
Second...1
Second...1
Second...2
Second...2
Second...2
Second...2
Second...2
Ожидаемый вывод
First...1
Second...1
First...1
Second...1
First...1
Second...1
First...1
Second...1
First...1
Second...1
First...2
First...2
First...2
First...2
First...2
Second...2
Second...2
Second...2
Second...2
Second...2
Ваши комментарии в коде:
synchronized (w2) {
w1.log(Thread.currentThread().getName() + "...1");
//!Этот блок кода должен выполнятся паралельно во всех потоках, но выполняется последовательно.
w2.log(Thread.currentThread().getName() + "...2");
//Этот должен выполнятся последовательно, и он так и делает.
}
неверны.
Секция synchronized синхронизирует не объект, а участок кода. Это означает, что вся секция будет выполнена «одним куском», не прерываясь другой секцией с тем же синхронизирующим объектом (это как раз ваш случай).
Таким образом, сначала код в потоке "First" приходит к синхронизирующей секции и выполняет её полностью, и только потом поток "Second". (Ну или в обратном порядке, как повезёт.)
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости