为什么Java同步不能按预期工作? [英] Why is Java synchronized not working as expected?

查看:105
本文介绍了为什么Java同步不能按预期工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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? The output keeps varying, sometimes it prints it right, other times it prints values from T1 mixed with T2 values. 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);
    }
}


推荐答案

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

Each A instance has its own B instance. The method addNew is an instance method of B. Therefore, the lock acquired implicitly during calls to addNew is the lock on the receiver B instance. 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.

这篇关于为什么Java同步不能按预期工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆