加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用布尔值双重检查成语

发布时间:2020-12-15 04:54:10 所属栏目:Java 来源:网络整理
导读:采取以下 java代码: public class SomeClass { private boolean initialized = false; private final ListString someList; public SomeClass() { someList = new ConcurrentLinkedQueueString(); } public void doSomeProcessing() { // do some stuff...
采取以下 java代码:

public class SomeClass {
  private boolean initialized = false;
  private final List<String> someList; 

  public SomeClass() {
    someList = new ConcurrentLinkedQueue<String>();
  }

  public void doSomeProcessing() {
    // do some stuff...
    // check if the list has been initialized
    if (!initialized) {
      synchronized(this) {
        if (!initialized) {
          // invoke a webservice that takes a lot of time
          final List<String> wsResult = invokeWebService();
          someList.addAll(wsResult);
          initialized = true;
        }
      } 
    }
    // list is initialized        
    for (final String s : someList) {
      // do more stuff...
    }
  }
}

诀窍是doSomeProcessing仅在某些条件下被调用.初始化列表是一个非常昂贵的过程,可能根本不需要它.

我读过有关为什么双重检查成语被打破的文章,当我看到这段代码时我有点怀疑.但是,这个例子中的控制变量是一个布尔值,因此我需要一个简单的写指令.

另外,请注意someList已被声明为final,并保留对并发列表的引用,其写入发生在读取之前;如果不是ConcurrentLinkedQueue,则列表是一个简单的ArrayList或LinkedList,即使它已被声明为final,也不需要在读取之前进行写入.

那么,上面给出的代码是否没有数据竞争?

解决方法

好的,让我们来获取Java语言规范.第17.4.5节 defines happens-before如下:

Two actions can be ordered by a
happens-before relationship. If one
action happens-before another,then
the first is visible to and ordered
before the second. If we have two
actions x and y,we write hb(x,y) to
indicate that x happens-before y.

  • If x and y are actions of the same
    thread and x comes before y in program
    order,then hb(x,y).
  • There is a
    happens-before edge from the end of a
    constructor of an object to the start
    of a finalizer (§12.6) for that
    object.
  • If an action x
    synchronizes-with a following action
    y,then we also have hb(x,y).
  • If
    hb(x,y) and hb(y,z),z).

It should be noted that the presence
of a happens-before relationship
between two actions does not
necessarily imply that they have to
take place in that order in an
implementation. If the reordering
produces results consistent with a
legal execution,it is not illegal.

然后继续讨论两个:

More specifically,if two actions share a happens-before relationship,they do not necessarily have to appear to have happened in that order to any code with which they do not share a happens-before relationship. Writes in one thread that are in a data race with reads in another thread may,for example,appear to occur out of order to those reads.

在您的实例中,线程检查

if (!initialized)

可以在看到添加到someList的所有写入之前看到初始化的新值,因此可以使用部分填充的列表.

请注意你的论点

Also,please notice that someList has been declared as final and keeps a reference to a concurrent list,whose writes happen-before reads

是无关紧要的.是的,如果线程从列表中读取一个值,我们可以得出结论,他也会在写入该值之前看到发生的任何事情.但如果它没有读取值呢?如果列表显示为空,该怎么办?即使它读取了值,也不意味着后续写入已经执行,因此列表可能看起来不完整.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读