Java 要在哪些对象上进行同步?为什么局部变量不好?
关于堆栈溢出,有很多关于同步的资料,但我仍然没有获得关于决定将哪个对象用作内在锁的高质量内容。作为经验法则,有人真的能给出一个好的答案吗 因此,我应该选择“monitor”作为实例变量还是局部变量或拥有该方法的实例?他们三个都做得很好。此外,原语值包装类使用“池”,因此也没有问题,因为线程“攻击”相同的锁 那么为什么这样做更好呢 在此(实例变量)上: 或在此基础上(局部变量): 他们都干得很好/一样。那么,为什么我读到当局部变量隐式使用池来存储对象时,我应该避免使用它们呢?在这种情况下,变量的范围有什么关系Java 要在哪些对象上进行同步?为什么局部变量不好?,java,multithreading,synchronization,Java,Multithreading,Synchronization,关于堆栈溢出,有很多关于同步的资料,但我仍然没有获得关于决定将哪个对象用作内在锁的高质量内容。作为经验法则,有人真的能给出一个好的答案吗 因此,我应该选择“monitor”作为实例变量还是局部变量或拥有该方法的实例?他们三个都做得很好。此外,原语值包装类使用“池”,因此也没有问题,因为线程“攻击”相同的锁 那么为什么这样做更好呢 在此(实例变量)上: 或在此基础上(局部变量): 他们都干得很好/一样。那么,为什么我读到当局部变量隐式使用池来存储对象时,我应该避免使用它们呢?在这种情况下,变量的范
谢谢 您应该避免使用存储在局部变量中的对象监视器,因为通常只有当前线程可以访问存储在局部变量中的对象。但由于在这种特殊情况下,局部变量实际上持有常量池中的全局共享对象,因此您不会遇到这种特殊问题 使用常量池对象监视器的问题如下:
String monitor = "monitor";
void methodA() {
synchronized (monitor){
//some code
}
}
。。。只有一个合并的常量对象
在类A的两个不同实例上运行的两个不同线程不能同时进入methodA
中的同步块,即使您已确保它应该是安全的(例如,您不接触静态共享状态)
更糟糕的是:在其他地方可能还有其他类B,这也恰好在常量“monitor”字符串上同步。现在,使用类B的线程将阻止其他不相关的线程使用类a
最重要的是,创建一个锁非常容易,因为您在不知不觉中共享了线程之间的锁。它们并不是“都工作得很好/相同”。在局部变量上进行同步完全没有任何效果,因为每个调用方都有自己的值。在实例成员而不是实例上进行同步可以实现更细粒度的控制:您可以为不同的操作使用不同的监视器,而这些操作不会相互干扰。我可以问一下,您为什么在第一段中说应该是安全的吗?在给定的情况下,我们将使用该方法同步所有实例,而不仅仅是一个实例。如果我们有所有线程共享的静态变量呢?那会毁了这个计划,不是吗?这就是为什么我们需要使用“公共”实例变量作为“监视器”。我说的对吗?是的,在这种情况下,您需要一个类的所有实例都通用的锁。我已对声明进行了限定,以澄清问题。
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
}
}