2015-10-15 2 views
-1

Почему код ниже не является тупиком и отлично работает?java basic multithreading

public class Concurrent { 

    public static void main(String[] args) { 
     Concurrent my = new Concurrent(); 
     my.method1(); 

    } 

    private synchronized void method1() { 
     System.out.println("method1"); 
     method2(); 
    } 

    private synchronized void method2() { 
     System.out.println("method2"); 
    } 
} 

Output: 
method1 
method2 

Когда я вызываю метод method1(), заблокирован. JVM или компилятор не может вызывать метод2(), потому что этот метод также синхронизируется монитором «моего» объекта. Но он отлично работает.

ответ

5

Почему код в вопросительном тупике не возникает?

Поскольку примитивные мьютексы (мониторы) являются реентерабельными. Когда поток, который находится внутри данного мьютекса, пытается его снова получить, он не блокируется.

JLS 17.1:

«Поток т может заблокировать конкретный монитор несколько раз, каждый разблокировать изменяет эффект одной операции блокировки.»

+0

Спасибо за ваши объяснения, я посчитал, что если мне нужен реентератор, я должен использовать java.util.concurrent.locks.ReentrantLock. Кроме того, я стараюсь, чтобы код в моем Вопросе был тупиком, но jvm или компилятор «оптимизировал» мой код, чтобы предотвратить тупик. –