这个函数是原子的吗?

时间:2015-03-17 08:56:50

标签: java multithreading thread-safety atomic nonblocking

我有一个用例,我需要在底层数据结构中添加值,并且需要维护订单。我使用ConcurrentLinkedQueue作为基础数据结构。以下是功能

public void put(V value) {
   concurrentLinkedQueue.add(value); 
}

这个语句是否是原子的,在某种意义上,如果两个线程试图放置值,线程A第一个(值V1)和线程B第二个(值V2),是否有可能首先添加V2,稍后添加V1。 / p>

2 个答案:

答案 0 :(得分:3)

答案是你的问题毫无意义。

如果两个线程以不同步的方式调用put,则

之间没有可观察到的差异
Thread 1     Thread 2

put          
add
             put
             add

Thread 1    Thread 2

put          
             put
             add
add

即使您使用方法synchronized,您的程序中也会有数据竞争,除非您在两个操作之间引入了适当的先发生关系。

问自己为什么线程调用put的顺序很重要,并确保通过适当的同步捕获此意图。

答案 1 :(得分:1)

背景:ConcurrentLinkedQueue在实现中是线程安全的。它是FIFO。因此它将保持插入顺序。

您的问题的答案:

  

此声明是否为原子

  

是否有可能首先添加V2,稍后添加V1

如果希望线程A在线程B之前插入值,则需要实现例程以显式处理插入顺序。 ConcurrentLinkedQueue中添加操作的原子性与此无关。这完全取决于哪个线程首先调用add()方法。

如果你想保持秩序(即 - FIFO),多线程可能不是你的答案。请问为什么需要多线程执行?我可以想到一些情况,你需要使用FIFO顺序进行多线程处理。只是因为您试图并行处理有序数据,而这些数据无法保证以相同的顺序完成处理。

如果绝对有必要使用并行处理,您可以使用如下的流行线程配置:

  1. 您可以拥有一个Manager-worker系统,其中管理器线程获取该作业,并将其委托给一个工作线程池,该工作线程将执行处理并根据作业数据结构中的某些属性重新排序结果(即 - 时间戳,序列号)。
  2. enter image description here

    1. 您可以拥有一个委托者线程来获取该作业,并将其委托给工作线程池,该工作线程将执行处理并将结果提交给另一个线程,该线程将根据作业中的某些属性执行重新排序。数据结构(即时间戳,序列号)。
    2. enter image description here

      在Manager或输出序列发生器线程内部,您可能必须维护数据缓冲区,这些数据缓冲区将在排序之前保存数据以进行分派。

      正如您所看到的,这样的实现可能非常复杂。所以你必须问自己,'你真的需要并行处理数据吗?'。

相关问题