1

我一直对以下情况感到困惑

MyClass 只有一个对象,有两个线程 T1、T2。现在一个线程说 T2 将能够使用具有唯一 MyClass 对象锁的同步方法 m1(),如果它试图访问 m1(),其他线程 T2 将被阻塞。

现在我的看法是,如果 T2 将尝试通过访问静态共享字段来访问静态同步方法 m2(),它将被阻塞,因为当前对象锁与 T1 并不能执行 m2() 并且如果有两个 Myclass 对象然后 T2 线程将能够访问 m1()。我是对还是错?

class MyClass
{

            public static int i = 5;

        public synchronized void m1()
        {
                System.out.println(i); //uses static field i of MyClass
            //T1 is executing this method
        }

            public static synchronized void m3()
            {
                //T2 will be able to call this method on same object lock while it is using
                //static field i???
                System.out.println(i);//uses static field i of MyClass
            }
}

这非常令人困惑,请帮助。提前致谢。

4

4 回答 4

6

不正确。因为无论方法的状态如何,在尝试调用它时都m2不会阻塞任何线程。synchronizedsynchronizedm1

获取对象上的锁不会阻止对该对象的访问,它只会阻止另一个线程同时获取同一对象上的锁的能力。如果其他线程没有尝试获取锁,它不会被阻塞。

于 2012-11-27T13:39:18.033 回答
6

现在我的看法是,如果 T2 将尝试访问非同步方法 m2() 它将被阻塞,因为当前对象锁与 T1

m2(),不同步,因此没有什么可以阻止它。这就是同步方法和非同步方法之间的区别。

当一个线程试图进入一个同步方法时,它会阻塞直到它可以获取到合适的监视器(锁)。当它退出方法时,它将释放锁。对于非同步方法,这些步骤都不会发生。

(顺便说一句,我个人建议在大多数情况下根本不使用同步方法。相反,在方法内同步,在在该类中知道的引用上。这样更容易推理代码,因为只有您的班级才能获得该锁。)

于 2012-11-27T13:39:25.787 回答
2

你错了。对象不会被synchronized块“锁定”,唯一发生的事情是其他synchronized块试图获取该对象的监视器必须等待。

总结一下:synchronized对非同步代码绝对没有阻塞作用。

于 2012-11-27T13:40:46.053 回答
1

线程进入同步方法 /block 时获取锁。因为 m2() 不是同步的,它会被线程 2 执行。记住,锁只有在有同步方法时才会出现

于 2012-11-27T13:40:00.520 回答