Из этой статьи я сделал вывод, что при использовании ключевого слова synchronized в объявлении метода поток, который успел успел первым залезть в метод, блокирует мьютекс класса для всех остальных потоков.
class MyClass {
private static String name1 = "Оля";
private static String name2 = "Лена";
public static synchronized void swap() {
String s = name1;
name1 = name2;
name2 = s;
}
}
class MyClass {
private static String name1 = "Оля";
private static String name2 = "Лена";
public static void swap() {
synchronized (MyClass.class) {
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Сверху представлены два идентичных по смыслу куска кода.
Значит ли это, что при наличии в классе двух и более synchronized методов одновременно может выполняться только один из них?
Мьютекс же у класса один, так что по идее ни один поток не сможет работать с каким-либо synchronized методом, пока первый поток не закончит свою работу, даже если методы никак не связаны между собой и не коим образом не конфликтуют.
Я себе написал тестовую программку и побаловался там с расстановкой synchronized, и результаты вроде как подтверждают мою теорию.
public class Solution {
public static void main(String[] args) {
Thread thread1 = new Thread(new Test1());
Thread thread2 = new Thread(new Test2());
thread1.start();
thread2.start();
}
public static synchronized void method1() {
System.out.println("Text1a");
System.out.println("Text2a");
System.out.println("Text3a");
System.out.println("Text4a");
}
public static synchronized void method2() {
System.out.println("Text1b");
System.out.println("Text2b");
System.out.println("Text3b");
System.out.println("Text4b");
}
static class Test1 implements Runnable {
@Override
public void run() {
method1();
}
}
static class Test2 implements Runnable {
@Override
public void run() {
method2();
}
}
}
В таком случае результаты всегда выводятся в консоль последовательно. Если же убрать один synchronized - вразнобой.