关于可见性的Java并发问题
我读到关于可见性的Java并发问题,java,multithreading,Java,Multithreading,我读到synchronized方法或块提供了两个特性:“互斥”和“可见性”。我想知道两件事 public class A{ private final Object lock = new Object(); private C obj = new C(); public void methodA(){ synchronized(lock){ obj.x = 1; obj.y=3; } } public void
synchronized
方法或块提供了两个特性:“互斥”和“可见性”。我想知道两件事
public class A{
private final Object lock = new Object();
private C obj = new C();
public void methodA(){
synchronized(lock){
obj.x = 1;
obj.y=3;
}
}
public void methodB(C obj2){
synchronized(lock){
obj2.x = obj.x;
}
}
}
让我们假设有两个线程在类型为
a
的全局共享对象上调用methodA
,并且lock
由thread1
获取,现在在thread1
释放锁之后。现在的可见性是所有其他线程都将读取对obj
的更改?即,同步
块内的每个更改是否都可见?或者我应该将C对象更改为volatile
以使其更改对其他人可见吗?使obj
将引用C对象volatile
。i、 e.在同步块外部可见。它不会影响该对象的成员
i、 e.对obj的重新分配将对另一个线程可见。对其成员的重新分配不会产生任何效果 生成
obj
volatile
将引用C对象volatile
。i、 e.在同步块外部可见。它不会影响该对象的成员
i、 e.对obj的重新分配将对另一个线程可见。对其成员的重新分配不会产生任何效果
同步块内的所有更改都将可见吗
是的,就是这个主意。定义发生在关系之前。特别是:
监视器上的解锁发生在监视器上的每个后续锁定之前
因此,当thread2获得锁时,您可以保证它将看到thread1在持有同一锁时所做的更改
我是否应该将C对象更改为volatile以使其更改对其他人可见
volatile保证,如果您编写:obj=newc()
在某个地方,后续读取obj
将看到它现在引用了一个新对象。但是,它没有就obj的“内容”提供任何此类保证。所以如果你写:obj.x=someValue代码>,由于obj是易失性的,您不能保证更改对另一个线程可见。除非你把x
也变成易变的
同步块内的所有更改都将可见吗
是的,就是这个主意。定义发生在关系之前。特别是:
监视器上的解锁发生在监视器上的每个后续锁定之前
因此,当thread2获得锁时,您可以保证它将看到thread1在持有同一锁时所做的更改
我是否应该将C对象更改为volatile以使其更改对其他人可见
volatile保证,如果您编写:obj=newc()
在某个地方,后续读取obj
将看到它现在引用了一个新对象。但是,它没有就obj的“内容”提供任何此类保证。所以如果你写:obj.x=someValue代码>,由于obj是易失性的,您不能保证更改对另一个线程可见。除非将x
也设置为易失性。否,否则访问obj
字段仍然不是线程安全的。锁定对象上的同步仅允许执行线程安全操作,以便将值写入此块中的obj
字段
UPD:obj
的volatile
对您没有帮助,因为您没有更改此字段自身的参考值。否,访问obj
字段仍然不是线程安全的。锁定对象上的同步仅允许执行线程安全操作,以便将值写入此块中的obj
字段
UPD:volatile
forobj
对您没有帮助,因为您不会更改此字段自身的参考值
现在的可见性是所有其他线程都将读取对obj的更改
对于该锁,仅同步块内的线程
同步块内的所有更改都将可见吗
大概吧。为了保证可见性,线程必须位于同步块内
或者我应该将C对象更改为volatile
如果您没有同步,这将不会有任何帮助,也不会在这里产生任何影响volatile
只会更改obj
引用的行为,而不会更改其字段
现在的可见性是所有其他线程都将读取对obj的更改
对于该锁,仅同步块内的线程
同步块内的所有更改都将可见吗
大概吧。为了保证可见性,线程必须位于同步块内
或者我应该将C对象更改为volatile
如果您没有同步,这将不会有任何帮助,也不会在这里产生任何影响volatile
只会更改obj
引用的行为,而不会更改其字段。要回答您的问题,另一种方法可以让您访问变量obj,而无需锁定。您必须确保的是,对obj的所有访问都必须小心地通过锁进行保护,以便obj不会处于不一致的状态(由程序员定义)
在您的特定示例中,它看起来足够一致。要回答您的问题,另一种方法可以简单地让您访问变量obj,而不需要锁。您必须确保的是,对obj的所有访问都必须小心地通过锁进行保护,以便obj不会处于不一致的状态(由程序员定义)
在您的特定示例中,它对我来说已经足够一致了。我不是专家,所以请耐心对待mei。我想确保我正确理解每一件事。如果您想确切了解Java中并发的工作原理,那么这本书就是您能得到的最好的书。我不是专家,所以请耐心对待mei