下面这两个同步块是否互斥?

发布于 2022-09-06 23:21:05 字数 230 浏览 29 评论 0

Object obj=new Object();
Object obj2=obj;
synchronized(obj){}
synchronized(obj2){}

又如果这样呢?

Object obj=new Object();
synchronized(obj){}
obj=new Object();
synchronized(obj){}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

予囚 2022-09-13 23:21:05

上面两个 synchronized 块是互斥的.
所以基于这种锁对象可能被误用的情况, 建议用单独的 final 对象做锁, 而不要用与业务相关的变量:

final Object lock = new Object();
此岸叶落 2022-09-13 23:21:05

锁这个标记是在 对象的Header的markword中存在的,是和一个对象绑定的,而不是和对象的引用绑定,所以第一个问题是互斥的,你的第二个问题有问题,因为你写synchronized(obj){}的时候,一般是以内部类的形式写在runnable或者Thread中,但是内部类引用的外部变量就必须是final的,而你这个obj都变了,就不是final,所以这段代码你是咋写出来的?

∞梦里开花 2022-09-13 23:21:05

针对问题:如果多个线程在并发执行执行拥有相同锁的同步块synchronized(obj){}时,锁对象obj被另一个线程给修改了指向,这个同步是否会失效?我有测试过这种情况没有失效,可能是因为即便obj引用指向变了,当前还没有执行完的同步块之间还是互斥的,因为对象还没有被回收还在使用中。如果只有一个同步块没有执行完,修改obj指向后,又执行了一个synchronized(obj){},这个时候它们是不是互斥的呢?

测试代码:

    static Object obj=new String("a");
    public static void main(String[] args) throws InterruptedException {
        class a extends Thread{
            @Override
            public void run() {
                synchronized(obj){
                    for (int i = 0; i < 10000; i++) {
                        if(i%10==0)System.out.println(obj+",0");
                    }
                }
            }
        }
        new a().start();
        Thread.sleep(10);
        obj=new String("b");
        class b extends Thread{
            @Override
            public void run() {
                synchronized(obj){
                    for (int i = 0; i < 10000; i++) {
                        if(i%10==0)System.out.println(obj+",1");
                    }
                }
            }
        }
        new b().start();
    }

测试结果:两个线程输出有交叉,同步确实会失效

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文