关于同步的堆栈溢出有很多资料,但是关于确定哪个对象用作内部锁,我仍然没有获得高质量的内容。凭经验可以实际回答一个好答案吗?
那么我应该选择“监视器”作为实例变量或局部变量还是拥有该方法的实例?他们三个都做得很好。同样,原始值包装器类使用“池”,所以在那里也没有问题,因为线程“攻击”相同的锁。
那么为什么更好地做到这一点(这个):
class A {
void methodA(){
synchronized (this){
//some code
}
}
}
在此(实例变量)上:
class A {
String monitor = "monitor";
void methodA(){
synchronized (monitor){
//some code
}
}
}
或以上(局部变量):
class A {
void methodA(){
String monitor = "monitor";
synchronized (monitor){
//some code
}
}
}
它们都工作正常/相同。那么,为什么我读到我应该避免在局部变量隐式使用池存储对象时避免局部变量?在这种情况下,变量的作用范围是什么?
谢谢!
您应该避免使用监视存储在局部变量中的对象的监视器,因为通常只有当前线程才能访问存储在局部变量中的对象。但是由于在这种特殊情况下,局部变量实际上从常量池中保存了一个全局共享的对象,因此您不必为此烦恼。
使用常量池对象的监视器的问题如下:
String monitor = "monitor";
void methodA() {
synchronized (monitor){
//some code
}
}
...是只有一个合并的常量对象。
methodA
即使已确保应该安全(例如,您不触摸静态共享状态),在A类的两个不同实例上运行的两个不同线程也无法同时进入同步块。
更糟糕的是:在其他地方可能还有其他一些B类,这也恰好在常量“监视”字符串上进行同步。现在,使用类B的线程将阻止其他不相关的线程使用类A。
最重要的是,创建死锁非常容易,因为您不知不觉间在线程之间共享锁。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句