Java 并发数据结构的使用示例?

Java 并发数据结构的使用示例?,java,c#,multithreading,data-structures,concurrency,Java,C#,Multithreading,Data Structures,Concurrency,因此,最近有很多关于并发和多线程的讨论,这是有道理的,但我很难看到实际应用程序 例如,.NET最近添加的concurrentdirectionary,ConcurrentBag,ConcurrentStack,ConcurrentQueue,等等 有哪些具体的实例可以说明这些措施何时发挥作用?理想情况下,我想要一些易于关联的场景,其中非并发的场景会失败,或者并发的场景会更快,因为易于并行 我主要感兴趣的是ConcurrentDictionary,如果这样可以更容易地提供示例的话。当我想到它的时候

因此,最近有很多关于并发和多线程的讨论,这是有道理的,但我很难看到实际应用程序

例如,.NET最近添加的
concurrentdirectionary
ConcurrentBag
ConcurrentStack
ConcurrentQueue
,等等

有哪些具体的实例可以说明这些措施何时发挥作用?理想情况下,我想要一些易于关联的场景,其中非并发的场景会失败,或者并发的场景会更快,因为易于并行

我主要感兴趣的是
ConcurrentDictionary
,如果这样可以更容易地提供示例的话。当我想到它的时候,我不明白并发是如何帮助提高速度的

假设您有一个想要添加到其中的数据源。跨分布在8个核上的8个线程对数据源进行迭代的速度是否与一个线程的速度相似,因为在这两种情况下,您都是从一端开始,然后转到另一端,而对于同步线程,在添加已经添加的数据时不会有任何争用


基本上,我想了解并发如何使程序更快,以及在什么情况下非并发实现会失败,因为我目前似乎想不出有多少实例在这方面有用。(初级语言C#)

通常,并发数据结构的添加速度比不支持并发修改的数据结构慢。如果你一次只添加一件东西。也就是说,如果您的代码只是执行以下操作的单个线程:

foreach (var item in list)
{
    AddItemToDataStructure(item);
}
如果数据结构是
Dictionary
,则运行速度将快于
ConcurrentDictionary

但是,如果您有多个线程针对
concurrentdirectionary
执行此操作,那么您的速度确实会有所提高。更新字典所涉及的大量工作包括确定项的去向以及是否已经存在具有该键的项。这项工作可以由多个线程同时完成。只有最终插入(即更新内部数据结构)需要某种同步,以防止数据结构损坏。这种同步在大多数情况下都是非常小的

(以上只是一个简单的解释,但我想你明白了。)

至于
ConcurrentQueue
ConcurrentStack
,它们并不是让事情变得更快,而是让事情变得可能。例如,假设有两个线程从某个外部源读取数据,一个线程处理读取的数据。你有两个生产者和一个消费者。它们通过共享队列进行通信。因此,您有两个线程可以执行此操作:

while data is available
    read data
    add data to shared queue
有一个线程正在执行此操作:

while not end of program
    while data is in queue
        read data from queue
        process data
对于非并发数据结构(即
队列
堆栈
),如果用锁包装这些数据结构,这是可能的,但要做到这一点却异常困难。如果你想消除轮询循环,那就更难了。并发数据结构可以为您完成所有这些

结果是,使用
ConcurrentQueue
很可能比在
Queue
周围包装一个简单的同步包装器要快


并发允许多个线程同时执行不同或相关的任务,从而使程序更快。并发数据结构通过在线程之间提供可靠的通信来促进这一点。此外,并发数据结构的性能通常优于包含在简单同步包装器中的相应非并发数据结构。

一般来说,并发数据结构的添加速度比不支持并发修改的数据结构慢。如果你一次只添加一件东西。也就是说,如果您的代码只是执行以下操作的单个线程:

foreach (var item in list)
{
    AddItemToDataStructure(item);
}
如果数据结构是
Dictionary
,则运行速度将快于
ConcurrentDictionary

但是,如果您有多个线程针对
concurrentdirectionary
执行此操作,那么您的速度确实会有所提高。更新字典所涉及的大量工作包括确定项的去向以及是否已经存在具有该键的项。这项工作可以由多个线程同时完成。只有最终插入(即更新内部数据结构)需要某种同步,以防止数据结构损坏。这种同步在大多数情况下都是非常小的

(以上只是一个简单的解释,但我想你明白了。)

至于
ConcurrentQueue
ConcurrentStack
,它们并不是让事情变得更快,而是让事情变得可能。例如,假设有两个线程从某个外部源读取数据,一个线程处理读取的数据。你有两个生产者和一个消费者。它们通过共享队列进行通信。因此,您有两个线程可以执行此操作:

while data is available
    read data
    add data to shared queue
有一个线程正在执行此操作:

while not end of program
    while data is in queue
        read data from queue
        process data
对于非并发数据结构(即
队列
堆栈
),如果用锁包装这些数据结构,这是可能的,但要做到这一点却异常困难。如果你想消除轮询循环,那就更难了。并发数据结构可以为您完成所有这些

结果是,使用
ConcurrentQueue
很可能比在
Queue
周围包装一个简单的同步包装器要快

并发允许多个线程同时执行不同或相关的任务,从而使程序更快。并发数据结构通过在线程之间提供可靠的通信来促进这一点。此外,并发数据结构将