Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.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_Concurrency_Volatile - Fatal编程技术网

Java 这是不稳定的还是结果不可预测?

Java 这是不稳定的还是结果不可预测?,java,multithreading,concurrency,volatile,Java,Multithreading,Concurrency,Volatile,控制线程执行的kill变量中是否需要volatile public class MyThread extends Thread{ private boolean kill = false; public void killThread(){ kill = true; } @Override public void run(){ while(!kill){ //do stuff

控制线程执行的
kill
变量中是否需要
volatile

public class MyThread extends Thread{  

  private boolean kill = false;  

  public void killThread(){  
      kill = true;  
  }  

  @Override  
  public void run(){  
     while(!kill){  
                 //do stuff  
     }  
  }  

}  
例如,如果在代码的其他部分(另一个线程)中,我执行
theThreadRef.killThread()
我应该期望线程停止,还是由于没有将
kill
声明为
volatile
而导致结果不可预测?我对此不确定,因为我通过
killThread
方法更新了
kill


谢谢

是的,
kill
是线程之间共享的变量,必须是
易失性的
。但是,考虑使用java的本地中断机制,涉及代码>线程。中断()/<代码>和<代码>线程。中断()/>代码,以实现您所需要的。这样您就不需要保留自己的变量。

是的,
kill
是线程之间共享的变量,必须是
易失性的。但是,考虑使用java的本地中断机制,涉及代码>线程。中断()/<代码>和<代码>线程。中断()/>代码,以实现您所需要的。这样就不需要保留自己的变量。

是的。如果未将
kill
声明为
volatile
,则其他线程可能会在其他线程执行新赋值后继续读取旧值。值更新的时间或时间是未定义的,因此从这个意义上说,行为是不可预测的(在实践中,新的赋值最终变得可见)


但是,由于基本布尔值的赋值是原子性的,因此该值将始终是“正确/有效”值(即
true
false
且永远不是无效值)。因此,从这个意义上讲,行为并非完全不可预测(代码不会崩溃等)。请注意,对于
long
类型或非基本对象,情况并非如此。Primitive int类型也具有与Primitive boolean相同的属性,这在标准库的String类实现中用于优化哈希代码计算是出了名的

是的。如果未将
kill
声明为
volatile
,则其他线程可能会在其他线程执行新赋值后继续读取旧值。值更新的时间或时间是未定义的,因此从这个意义上说,行为是不可预测的(在实践中,新的赋值最终变得可见)


但是,由于基本布尔值的赋值是原子性的,因此该值将始终是“正确/有效”值(即
true
false
且永远不是无效值)。因此,从这个意义上讲,行为并非完全不可预测(代码不会崩溃等)。请注意,对于
long
类型或非基本对象,情况并非如此。Primitive int类型也具有与Primitive boolean相同的属性,这在标准库的String类实现中用于优化哈希代码计算是出了名的

谢谢。我主要关心的是这段代码是否具有可预测的行为。所以我们不能确定线程是否会结束,对吗?你的代码肯定有不可预知的行为。更重要的是,由于被称为“提升”的优化技术,线程从未观察到对
kill
的更改,这几乎是一种典型的行为。编译器可以假定,
kill
永远不会从其他线程更改,并且根据代码的其余部分,甚至可以将
kill
的读取移到循环外部,并将循环变成
while(true)
。即使没有提升,
kill
的值也将写入线程本地存储,并且永远不会更新。@Jim只是不必担心JIT编译器可能进行的优化的细节。如果你把
volatile
放在
kill
变量上,就可以了。更新确实是原子的,但是如果没有
volatile
它就不能保证被读取线程观察到。AtomicBoolean甚至没有lazySet,你在看1.5吗,lazySet从1.6开始提供:谢谢。我主要关心的是这段代码是否具有可预测的行为。所以我们不能确定线程是否会结束,对吗?你的代码肯定有不可预知的行为。更重要的是,由于被称为“提升”的优化技术,线程从未观察到对
kill
的更改,这几乎是一种典型的行为。编译器可以假定,
kill
永远不会从其他线程更改,并且根据代码的其余部分,甚至可以将
kill
的读取移到循环外部,并将循环变成
while(true)
。即使没有提升,
kill
的值也将写入线程本地存储,并且永远不会更新。@Jim只是不必担心JIT编译器可能进行的优化的细节。如果您将
volatile
放在
kill
变量上,就可以了。更新确实是原子的,但是如果没有
volatile
它就不能保证被读取线程观察到。AtomicBoolean甚至没有lazySet,您是否在看1.5,lazySet从1.6开始就可用: