Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于可见性的Java并发问题_Java_Multithreading - Fatal编程技术网

关于可见性的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
for
obj
对您没有帮助,因为您不会更改此字段自身的参考值

现在的可见性是所有其他线程都将读取对obj的更改

对于该锁,仅同步块内的线程

同步块内的所有更改都将可见吗

大概吧。为了保证可见性,线程必须位于同步块内

或者我应该将C对象更改为volatile

如果您没有同步,这将不会有任何帮助,也不会在这里产生任何影响
volatile
只会更改
obj
引用的行为,而不会更改其字段

现在的可见性是所有其他线程都将读取对obj的更改

对于该锁,仅同步块内的线程

同步块内的所有更改都将可见吗

大概吧。为了保证可见性,线程必须位于同步块内

或者我应该将C对象更改为volatile


如果您没有同步,这将不会有任何帮助,也不会在这里产生任何影响
volatile
只会更改
obj
引用的行为,而不会更改其字段。

要回答您的问题,另一种方法可以让您访问变量obj,而无需锁定。您必须确保的是,对obj的所有访问都必须小心地通过锁进行保护,以便obj不会处于不一致的状态(由程序员定义)


在您的特定示例中,它看起来足够一致。

要回答您的问题,另一种方法可以简单地让您访问变量obj,而不需要锁。您必须确保的是,对obj的所有访问都必须小心地通过锁进行保护,以便obj不会处于不一致的状态(由程序员定义)


在您的特定示例中,它对我来说已经足够一致了。

我不是专家,所以请耐心对待mei。我想确保我正确理解每一件事。如果您想确切了解Java中并发的工作原理,那么这本书就是您能得到的最好的书。我不是专家,所以请耐心对待mei