簡體   English   中英

方法上的Java線程同步

[英]Java thread synchronization on methods

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

由於我已經同步m1(),我希望thread-1完全打印值0 ... 10然后thread-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

您已經synchronized了一個實例方法。 它將在實例本身上同步。 但是,每個Thread都使用不同的實例,即。 它們每個都在不同的對象上synchronized ,因此不會相互阻塞。

您需要共享您的Test實例

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

或在不同的共享對象上使用synchronized 您可以通過將鎖定對象作為構造函數參數傳遞或使用靜態字段引用來執行此操作。

synchronized方法的問題在於它鎖定了this 在您的情況下,您有兩個不同的實例 - 每個實例都有不同的this引用。 在方法上使用synchronized字與執行此操作相同:

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();

   }   

}

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM