Возникла проблема: я слышал, что если мы блокируем мьютекс на уровне объекта, то все остальные синхронизированные методы тоже блокируются, чтобы ограничить к ним доступ в пределах одного потока, и только когда поток снимет блокировку (закончит выполнение) во всех методах, то тогда второй поток сможет занять мьютекс общего ресурса (нашего объекта). Но почему-то такая теория на практике не дала плоды, а лишь наоборот - больше запутала меня, ведь в итоге второй поток все равно имеет доступ ко второму методу, пока первый занял мьютекс объекта и занимается первым методом, имея вот такой вывод:
0 Thread-0
1 Thread-0
2 Thread-0
0 Thread-1
1 Thread-1
2 Thread-1
Hey! Thread-1
You pretty and funny! Thread-1
I love you so much! Thread-1
Hey! Thread-0
You pretty and funny! Thread-0
I love you so much! Thread-0
Проясните мне пожалуйста, что у меня не так в коде, или может я вовсе ошибся с такой теорией! Но вот код, который я использовал для теста:
public class Task1SyncObj {
public static void main(String[] args) {
Start start = new Start(); // создание общего ресурса;
MyClass thread = new MyClass(start); // создание первого потока;
MyClass thread_2 = new MyClass(start); // создание второго потока;
thread.start();
thread_2.start();
}
public static class MyClass extends Thread {
Start startMethod; // общий ресурс, объект;
public MyClass(Start startMethod) {
this.startMethod = startMethod; // инициализация;
}
@Override
public void run() {
startMethod.start(); // запуск синхронизированного метода;
startMethod.start_With_Hello(); // запуск еще одного синхронизированного потока;
}
}
public static class Start {
/*
Синхронизированный метод start() гарантирует взаимоисключение между двумя созданными потоками в методе main()
посредством ключевого слова synchronized. Данный код эквивалентен: synchronized(this) {
...
}
*/
public synchronized void start() {
for(int i = 0; i<3; i++) {
System.out.println(i + " " + Thread.currentThread().getName());
}
System.out.println();
}
public synchronized void start_With_Hello() {
System.out.println("Hey! " + Thread.currentThread().getName());
System.out.println("You pretty and funny! " + Thread.currentThread().getName());
System.out.println("I love you so much! " + Thread.currentThread().getName());
System.out.println();
}
}
}