java - 原子引用的保证

标签 java multithreading concurrency java.util.concurrent

AtomicReference 的语义是什么? ?
如果我这样做:

AtomicReference<CustomObject> ref = new AtomicReference<CustomObject>();

然后我这样做:

public void someMethod(){  
 //do something  

 ref.set(loadNewData());  

}  

private final Sempahore updatePermit = new Sempahore(1);  

private CustomObject loadNewData(){  
     CustomObject obj = null;  
     if (updatePermit.tryAcquire()) {  
        obj = ...; //do the loading and create Object  
        updatePermit.release();  
    } else {  
        //update already running, wait  
        updatePermit.acquire();  
        //release the permit immediately  
        updatePermit.release();  
        obj = ref.get(); //????
    }  
    return obj;    
}    

是否有在线obj = ref.get(); //????保证 get将返回 CustomObject最新最新版本?
这与 assylias 对 post 的回答有关。 :

最佳答案

实际上,您的代码存在竞争条件,可能会导致新数据丢失:

  1. 第一个调用者进入 loadNewData 并开始加载新数据(有信号量)
  2. 第二个调用者无法获取信号量并在获取时等待
  3. 第一个调用者完成加载并释放信号量(但尚未返回新数据)
  4. 第二个调用者获取信号量,调用 ref.get() 并获取数据
  5. 第一个调用者返回新数据并传递给 ref.set()
  6. 第二个调用者返回数据,该数据在传递给ref.set()时覆盖新数据

由于 someMethod() 总是加载新数据,并且您总是希望调用者在新数据加载时等待,所有这些额外的东西是没用的。只需在整个 block 周围使用一个简单的同步块(synchronized block)(或锁)并放弃原子引用。根据链接的帖子,似乎您只想执行一次此操作,因此请使用初始化标志。

private boolean _initialized;

public synchronized void loadLatestData() {
  if(!_initialized) {
      // load latest data ...
      _initialized = true;
  }
}

关于java - 原子引用的保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13362427/

相关文章:

java - 可互换的键/值 HashMap Set 结构

java - 如何在java中清除BufferedImage的像素?

java - 使用 XYDataset(JFreeChart) 添加双变量值到 XySeries

java - java中获取查询的方法的并行加速问题

android - ListView 的多线程使错误的项目/根本没有项目出现

python - Urllib 和并发 - Python

java - 流在 for 循环中不起作用

java - 这个java程序中存在多线程冲突。怎么解释呢?

java - 寻找 Java 聪明的任务调度器和执行器

concurrency - 通知所有 goroutines