2013-06-29 79 views
1

在下面的代碼,我試圖找出線程在synchronized塊處理執行:線程執行序列

public class ThreadExp { 
    public static void main(String[] args) throws InterruptedException { 
     MyRunnable r = new MyRunnable(); 
     Thread t1 = new Thread(r, "Thread1"); 
     Thread t2 = new Thread(r, "Thread2"); 
     t1.start(); 
     t2.start(); 
    } 

} 

class MyRunnable implements Runnable { 

    @Override 
    public void run() { 
     callFn(); 
    } 

    private void callFn() { 
     System.out.println(Thread.currentThread().getName() + ": entered callSync()"); 
     synchronized (Thread.currentThread()) { 
      System.out.println(Thread.currentThread().getName() + ": inside sync"); 
      try { 
       Thread.currentThread().sleep(5000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println(Thread.currentThread().getName() + " leaving sync"); 
     } 
     System.out.println(Thread.currentThread().getName() + ": leaving callSync()"); 
    } 
} 

實際輸出:

Thread1: entered callFn() 
    Thread2: entered callFn() 
    Thread1: inside sync block 
    Thread2: inside sync block 
// 5000 millisec sleep 
    Thread2 leaving sync block 
    Thread1 leaving sync block 
    Thread2: leaving callFn() 
    Thread1: leaving callFn() 

而我預期的東西如:

Thread1: entered callFn() 
Thread2: entered callFn() 
Thread1: inside sync block 
// 5000 millisec sleep 
Thread1 leaving sync block 
Thread1: leaving callFn() 
Thread2: inside sync block 
Thread2 leaving sync block 
Thread2: leaving callFn() 

總的來說,我認爲Thread1會獲得鎖,然後進入睡眠。只有在線程1完成後,線程2才能進入同步塊。

+0

同步線程對象將永遠不會阻塞。它怎麼可能?多線程嘗試輸入鎖時發生爭用,但在您的情況下,每個線程正在輸入唯一的鎖。 – dlev

回答

5

正在同步線程本身上:

synchronized (Thread.currentThread()) 

所以每個線程都有自己的鎖,他們可以同時執行​​塊。

如果您希望​​塊一次只能由一個線程運行,則需要使用相同的鎖。

在您的例子,它可能僅僅是this,因爲Runnable實例同樣爲你的兩個線程:

synchronized(this) {...} 

然後輸出如下:當前

Thread1: entered callSync() 
Thread1: inside sync 
Thread2: entered callSync() 
Thread1 leaving sync 
Thread1: leaving callSync() 
Thread2: inside sync 
Thread2 leaving sync 
Thread2: leaving callSync() 
+0

在Thread.currentThread()上同步似乎完全沒用 - 坦率地說,看起來像一個錯誤。有沒有這種情況有用? – user949300

+0

@ user949300它所做的是創建一個內存屏障,但有很多更好的方法來實現它。 – assylias

+0

謝謝 - 它的使用有點意義。 – user949300