简体   繁体   English

为什么 Java 同步没有按预期工作?

[英]Why is Java synchronized not working as expected?

I'm trying to figure out how synchronized methods work.我试图弄清楚同步方法是如何工作的。 From my understanding I created two threads T1 and T2 that will call the same method addNew , since the method is synchronized shouldn't it execute all the iterations of the for loop for one thread and then the other?根据我的理解,我创建了两个线程T1T2 ,它们将调用相同的方法addNew ,因为该方法是同步的,它不应该为一个线程执行 for 循环的所有迭代,然后是另一个线程吗? The output keeps varying, sometimes it prints it right, other times it prints values from T1 mixed with T2 values.输出不断变化,有时它打印正确,有时它打印来自 T1 的值与 T2 值混合。 The code is very simple, can someone point out what am I doing wrong?代码很简单,有人能指出我做错了什么吗? Thank you.谢谢。

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

Each A instance has its own B instance.每个A实例都有自己的B实例。 The method addNew is an instance method of B .方法addNewB的实例方法。 Therefore, the lock acquired implicitly during calls to addNew is the lock on the receiver B instance.因此,在调用addNew期间隐式获取的锁是接收方B实例上的锁。 Each thread is calling addNew on a different B , and therefore locking on different locks.每个线程都在不同的B上调用addNew ,因此锁定在不同的锁上。

If you want all B instances to use a common lock, create a single shared lock, and acquire it in the body of addNew .如果您希望所有B实例都使用一个公共锁,请创建一个共享锁,并在addNew的主体中获取它。

Both A objects have their own B object.两个A对象都有自己的B对象。 You need them to share a B so the synchronization can have an effect.您需要它们共享一个B以便同步生效。

try this :尝试这个 :

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM