2013-09-27 55 views
1

我正在嘗試使用方法Synchronization運行示例線程模塊,但結果不符合預期。方法上的Java線程同步

由於我已經同步了m1(),我期望線程1完全打印值0 ... 10,然後線程2開始運行。

但是,在這種情況下,數字印刷交替...

package threadexample; 

public class Test implements Runnable{ 
    public void run(){ 
     m1(); 
    } 
    public synchronized void m1(){ 
     for (int i = 0; i < 10; i ++){ 
      System.out.println(Thread.currentThread().getName() + " Value of i = " + i); 
     } 
    } 
    Test(String threadname){ 
     super(); 
    } 

    public static void main(String[] args){ 
      Test a = new Test("A"); 
      Test b = new Test("B"); 
      Thread t1 = new Thread(a); 
      Thread t2 = new Thread(b); 
      t1.start(); 
      t2.start(); 

    } 

} 



Output: 

Thread-0 Value of i = 0 
Thread-1 Value of i = 0 
Thread-0 Value of i = 1 
Thread-1 Value of i = 1 
Thread-0 Value of i = 2 
Thread-1 Value of i = 2 
Thread-0 Value of i = 3 
Thread-1 Value of i = 3 
Thread-0 Value of i = 4 
Thread-1 Value of i = 4 
Thread-0 Value of i = 5 
Thread-1 Value of i = 5 
Thread-0 Value of i = 6 
Thread-1 Value of i = 6 
Thread-0 Value of i = 7 
Thread-1 Value of i = 7 
Thread-0 Value of i = 8 
Thread-1 Value of i = 8 
Thread-0 Value of i = 9 
Thread-1 Value of i = 9 

回答

3

您已經​​一個實例方法。它將在實例本身上進行同步。但是,您的每個Thread s正在使用不同的實例,即。它們在不同的對象上各自爲​​,因此不會彼此阻塞。

你需要分享您的Test實例

Test a = new Test("A"); 
Thread t1 = new Thread(a); 
Thread t2 = new Thread(a); 

或不同的共享對象使用​​。您可以通過傳遞鎖對象作爲構造函數參數或使用靜態字段引用來完成此操作。

+0

怎麼了downvote? –

1

方法​​的問題是它鎖定在this上。在你的情況下,你有2個不同的實例 - 他們每個人都有不同的this參考。一個方法使用​​字是一樣的這樣做:

public void m1() { 
    synchronized(this) { 
     // Critical code section here 
    } 
} 

如果你想要做你描述你的代碼看起來應該是這樣的鎖:

public class Test implements Runnable{ 

    private final static Object lock = new Object(); 

    public void run(){ 
     m1(); 
    } 

    public void m1(){ 
     synchronized(lock) { 
      for (int i = 0; i < 10; i ++){ 
       System.out.println(Thread.currentThread().getName() + " Value of i = " + i); 
      } 
     } 
    } 

    Test(String threadname){ 
     super(); 
    } 

    public static void main(String[] args){ 
     Test a = new Test("A"); 
     Test b = new Test("B"); 
     Thread t1 = new Thread(a); 
     Thread t2 = new Thread(b); 
     t1.start(); 
     t2.start(); 

    } 

} 

在這種情況下,您共享在兩個實例之間鎖定(因爲它是靜態的),這樣就鎖定了同一個對象,並按照您希望的方式進行同步。