为什么Java同步不能按预期工作?

时间:2017-05-26 15:56:55

标签: java multithreading synchronized

我正在试图找出同步方法的工作原理。根据我的理解,我创建了两个线程 T1 T2 ,它们将调用相同的方法addNew,因为该方法是同步的,不应该执行所有的迭代一个线程的for循环然后另一个线程的for循环?输出保持不变,有时它会正确打印,有时它会打印T1与T2值混合的值。代码很简单,有人可以指出我做错了什么吗?谢谢。

public class Main {
    public static void main(String[] args) {
        Thread t1 = new Thread(new A());
        Thread t2 = new Thread(new A());
        t1.setName("T1");
        t2.setName("T2");
        t1.start();
        t2.start();
    }
}

public class B {
    public synchronized void addNew(int i){
        Thread t = Thread.currentThread();
        for (int j = 0; j < 5; j++) {
            System.out.println(t.getName() +"-"+(j+i));
        }
    }
}

public class A extends Thread {
    private B b1 = new B();

    @Override
    public void run() {
        b1.addNew(100);
    }
}

3 个答案:

答案 0 :(得分:7)

每个A实例都有自己的B实例。方法addNewB的实例方法。因此,在调用addNew期间隐式获取的锁是对接收方B实例的锁定。每个线程在不同的addNew上调用B,因此锁定不同的锁。

如果您希望所有 B实例使用公共锁,请创建一个共享锁,并在addNew正文中获取它。

答案 1 :(得分:3)

两个A个对象都有自己的B个对象。您需要它们共享B,以便同步可以产生效果。

答案 2 :(得分:0)

尝试:

public class Main {
    public static void main(String[] args) {
        A a = new A();
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(a);
        t1.setName("T1");
        t2.setName("T2");
        t1.start();
        t2.start();
    }
}

 class B {
    public synchronized void addNew(int i){
        Thread t = Thread.currentThread();
        for (int j = 0; j < 5; j++) {
            System.out.println(t.getName() +"-"+(j+i));
        }
    }
}

 class A extends Thread {
    private B b1 = new B();

    @Override
    public void run() {
        b1.addNew(100);
    }
}