Java 这个函数是原子函数吗?

Java 这个函数是原子函数吗?,java,multithreading,thread-safety,atomic,nonblocking,Java,Multithreading,Thread Safety,Atomic,Nonblocking,我有一个用例,需要向底层数据结构添加值,并且需要维护顺序。我使用ConcurrentLinkedQueue作为底层数据结构。下面是函数 public void put(V value) { concurrentLinkedQueue.add(value); } 从某种意义上说,如果两个线程试图将值放在第一个线程(值V1)和第二个线程(值V2)上,那么这个语句是原子的吗?是否有可能先添加V2,然后再添加V1。答案是您的问题有点无意义 如果两个线程以不同步的方式调用put,那么这两个线程之

我有一个用例,需要向底层数据结构添加值,并且需要维护顺序。我使用
ConcurrentLinkedQueue
作为底层数据结构。下面是函数

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

从某种意义上说,如果两个线程试图将值放在第一个线程(值V1)和第二个线程(值V2)上,那么这个语句是原子的吗?是否有可能先添加V2,然后再添加V1。

答案是您的问题有点无意义

如果两个线程以不同步的方式调用
put
,那么这两个线程之间没有明显的差异

Thread 1     Thread 2

put          
add
             put
             add

即使将方法
同步化
,程序中也会出现数据竞争,除非在两个操作之间引入适当的“发生在之前”关系


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

答案是你的问题有点毫无意义

如果两个线程以不同步的方式调用
put
,那么这两个线程之间没有明显的差异

Thread 1     Thread 2

put          
add
             put
             add

即使将方法
同步化
,程序中也会出现数据竞争,除非在两个操作之间引入适当的“发生在之前”关系


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

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

您的问题的答案如下:

这句话是原子的吗

是否有可能先添加V2,然后再添加V1

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

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

如果偶然需要使用并行处理,您可以使用流行的线程配置,如下所示:

  • 您可以拥有一个管理器-工作线程系统,其中管理器线程获取作业,并将其委托给一个工作线程池,该工作线程池将根据作业数据结构中的某些属性(即时间戳、序列号)执行处理并重新排序结果
  • 您可以有一个delegator线程来获取作业,并将其委托给一个工作线程池,该工作线程池将进行处理,并将结果提交给另一个线程,该线程将根据作业数据结构中的某些属性(即时间戳、序列号)执行重新排序
  • 在Manager或Output Sequencer线程中,您可能必须维护数据缓冲区,在对数据进行排序以进行调度之前,这些缓冲区将保存数据


    如您所见,这样的实现可能相当复杂。所以你必须问自己,‘你真的需要并行处理数据吗?’

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

    您的问题的答案如下:

    这句话是原子的吗

    是否有可能先添加V2,然后再添加V1

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

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

    如果偶然需要使用并行处理,您可以使用流行的线程配置,如下所示:

  • 您可以拥有一个管理器-工作线程系统,其中管理器线程获取作业,并将其委托给一个工作线程池,该工作线程池将根据作业数据结构中的某些属性(即时间戳、序列号)执行处理并重新排序结果
  • 您可以有一个delegator线程来获取作业,并将其委托给一个工作线程池,该工作线程池将进行处理,并将结果提交给另一个线程,该线程将根据作业数据结构中的某些属性(即时间戳、序列号)执行重新排序
  • 在Manager或Output Sequencer线程中,您可能必须维护数据缓冲区,在对数据进行排序以进行调度之前,这些缓冲区将保存数据


    如您所见,这样的实现可能相当复杂。所以你必须问自己,‘你真的需要并行处理数据吗?’

    如果你能在多线程环境中准确定义单词first的含义,我们也许能够回答你的问题?@OldCurmudgeon by first,调用
    put
    @user592748的第一个线程-如果它们在同一时间调用-在可能发生的多线程和多核环境中会发生什么情况。@user592748-那么您应该为更新设置时间戳以保持顺序。你不应该