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

Why is Java synchronized not working as expected?

我正在尝试了解同步方法的工作原理。根据我的理解,我创建了两个线程 T1T2,它们将调用相同的方法 addNew,因为该方法是同步的,不应该它为一个线程执行 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);
    }
}

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

如果要所有 B个实例使用一个公共锁,创建一个共享锁,并在addNew的主体中获取它。

两个 A 对象都有自己的 B 对象。你需要他们共享一个 B 这样同步才能生效。

试试这个:

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