繁体   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