【问题标题】:Threads, Object state线程,对象状态
【发布时间】:2018-04-11 06:24:05
【问题描述】:
Class A{

private boolean connected = false;

public void doAction(){

if(connected){
//do something
}
else{
//do this
  }
   }

public void setConnected(boolean flag)
    {
       this.connected = flag;
    }
  }

我的项目中有上面的代码,它是一个单例。 setConnected() 方法会在某些条件下被触发(它只会被触发一次)。 doAction() 方法被调度器定期调用以执行一些操作。

我的问题是,如果单例对象的状态在构造后被修改(通过调用setConnected()),更新后的状态对进一步调用方法调用可见(定期调用doAction())?(注意:已连接变量不是易失的)。

【问题讨论】:

  • 你的 doAction 和 setConnected 方法是从不同的线程调用的吗?
  • 是的,它是从不同的线程调用的
  • 所以我强烈建议在你的情况下使用 volatile。仔细阅读我的答案以获得更多解释。

标签: java multithreading object thread-safety java-threads


【解决方案1】:

您的connected 变量不是volatile,这意味着,在其他线程进行任何写操作后,所有其他线程都不会获得更新的值guarantee。因此,我建议您将volatile 用于您的用例。 volatile 关键字确保所有线程都能看到most recent updated 值。

已编辑:

非易失性变量也可以在不同条件下刷新 CPU 缓存。

  1. 一个线程也可以从它的 CPU 中换出,强制它在获得下一个时间片时重新加载它的缓存。

  2. 线程在退出/或完成时刷新其所有更新值。如果您在线程(调用您的 setConnected 方法)之后创建一个新线程(调用 doAction)并且它成功完成它将获取更新的值,因为新线程每次都会为其创建一个新的上下文。

【讨论】:

  • 你的意思是,进一步的方法调用永远不会看到连接变量的更新值?如果是,那么线程缓存值何时发布到主内存?
  • 感谢您的回复,我还有一个疑问,在j2ee环境下,线程维护在公共线程池中,当执行完成时,线程不会被终止,而是返回到线程池中进一步的请求处理。在这种情况下,正如您在第 2 点中提到的,线程缓存刷新到主内存?
  • @girishbabu By point - 2 我试图解释如果线程完成其执行,则更新将在主内存上可用。因此,在完成该线程后,如果您创建任何线程,那么它将看到最新的值。是的,如果线程池刷新可能会延迟。因此,为了确保对更新值进行读写,请使用 volatile / synchronized / join 等。
猜你喜欢
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 2010-11-24
  • 2015-02-08
  • 1970-01-01
相关资源
最近更新 更多