1

我正在尝试使用方法 Synchronization 运行示例线程模块,但结果与预期不符。

由于我已经同步了 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
4

2 回答 2

3

你有synchronized一个实例方法。它将在实例本身上同步。但是,您的每个Threads 都使用不同的实例,即。它们各自synchronized位于不同的对象上,因此不会相互阻挡。

您需要共享您的Test实例

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

synchronized在不同的共享对象上使用。您可以通过将锁定对象作为构造函数参数传递或使用静态字段引用来做到这一点。

于 2013-09-27T00:24:53.247 回答
1

on 方法的问题synchronized在于它锁定了this. 在您的情况下,您有 2 个不同的实例 - 每个实例都有不同的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();

   }   

}

在这种情况下,您在 2 个实例之间共享锁(因为它是静态的),这样您就可以锁定同一个对象并按照您想要的方式进行同步。

于 2013-09-27T00:25:06.310 回答