我有一个有某种状态的类的对象。
此对象有两种方法(method1()
和method2()
),两种方法都在更改obj
的状态。
method1()
已同步,但method2()
未同步。
现在两个线程,thread1和threads2接近对象
- > threads1调用同步的method1()
- > thread2调用未同步的method2()
。
我在测试结果中发现的是method2()
正在正确执行,即使method1()
持有锁定。但我认为如果通过在方法上放置synchronized关键字来获取整个对象的锁定,则可以执行多少其他方法。它应该等待。
非常感谢您的意见。
答案 0 :(得分:2)
当我们说调用同步方法或块导致锁定时,所有这意味着线程专门获取锁。这并不意味着线程获取的锁定对象的状态会受到任何其他保护。
(内部锁附加到对象,包括类对象,这是语言设计者的方便。这个决定可能不是最好的。使用专用对象来锁定通常是一个更好的主意。)
您的未同步调用可能会破坏共享状态。除此之外,没有内存屏障,并且调用未同步方法的线程所做的更改可能不被其他线程看到。在进行重新排序代码等优化时,JIT不会考虑跨线程可见性问题。
可能很难预测未充分同步的代码会发生什么。
答案 1 :(得分:1)
但是我认为如果通过在方法上放置同步来获取整个对象的锁,那么就可以执行任何其他方法。它应该等待。
锁不知道它锁定了什么。它只是阻止其他线程获取同一个锁。
答案 2 :(得分:1)
这里有一些很好的答案,但我认为还有更多的细节。
我的测试结果发现,即使method1()有一个锁,方法2()也很乐意执行。
当线程进入synchronized
方法时,它会锁定与对象实例关联的监视器。其他线程可以根据需要在同一个对象实例上调用其他非同步方法。由thread1
持有的锁定不会以任何方式更改obj
。只有当thread2
也锁定相同的对象实例时才会被阻止。
但是我认为如果通过在方法上放置同步来获取整个对象的锁,那么就可以执行任何其他方法。它应该等待。
不,事实并非如此。如果每个方法调用都必须查看对象的方法是否被锁定,那么会有很大的性能损失。