Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单写器、不同读卡器与同一线程的性能_Java_Multithreading_Performance - Fatal编程技术网

Java 单写器、不同读卡器与同一线程的性能

Java 单写器、不同读卡器与同一线程的性能,java,multithreading,performance,Java,Multithreading,Performance,我有一个“订单管理器”应用程序,我采用“单编写器”方法处理订单事件,以避免任何竞争条件 因此,我有一个主线程,它忙于处理传入的订单事件,并在不进行任何阻塞调用的情况下处理这些事件 这个主线程还需要静态数据来验证订单事件等。因此,我将静态数据存储在内存缓存(java映射)中 我想了解通过主线程访问内存中静态数据的最有效方式 A) 主线程本身是否应该负责维护内存中的静态数据,以便每件事情只有一个线程,从而实现最大CPU吞吐量,避免任何与线程相关的争用/锁定 或 B) 我是否应该使用单独的专用线程将静

我有一个“订单管理器”应用程序,我采用“单编写器”方法处理订单事件,以避免任何竞争条件

因此,我有一个主线程,它忙于处理传入的订单事件,并在不进行任何阻塞调用的情况下处理这些事件

这个主线程还需要静态数据来验证订单事件等。因此,我将静态数据存储在内存缓存(java映射)中

我想了解通过主线程访问内存中静态数据的最有效方式

A) 主线程本身是否应该负责维护内存中的静态数据,以便每件事情只有一个线程,从而实现最大CPU吞吐量,避免任何与线程相关的争用/锁定

B) 我是否应该使用单独的专用线程将静态数据存储在ConcurrentHashmap中,并与我的主线程(单个编写器、不同的读线程)共享该映射。我在某个地方读到,只要有一个写线程,读线程的访问就可以通过使用特殊通道跨CPU核心进行优化。但是,对于第二种方法,我仍然必须使用ConcurrentHashMap,这将带来与线程和锁相关的延迟


我想听听大家对实现最大吞吐量的最佳方法的看法。

在线程之间共享状态有两种以上的方法。而且几乎不可能说哪一个更适合你的情况。正确的方法是对多个解决方案(jmh、jcstrees)进行基准测试

由于简单性、维护成本等原因,如果单线程能够提供足够的性能,则认为它是最佳解决方案。 但如果我们试图在一般情况下获得最大吞吐量,多线程是一个必要的缺点


如果计算/维护静态数据的成本太高,我会选择第二种方法,并添加一个。我会考虑使用发布不可变的映射,而不是CHM变量来解决这个问题。

< P>这取决于缓存中静态数据的性质。如果应用程序工作时数据没有更改,则可以在主线程中创建和填充该缓存,并在同一主线程中使用它。
但是如果缓存需要更新(定期或作为对某些事件的响应),那么最好有一个单独的线程来创建缓存,首先填充缓存,然后进行更新,因为如果您开始在主线程中执行缓存更新,那么在缓存更新完成之前,该主线程将无法处理订单。

这听起来像是一个经典的事件流处理。一个线程更简单,通常性能更高(线程间通信总是有一些成本)。如果有CPU密集型任务可以并发运行,则在单独的线程中执行作业会带来好处,而在顺序流处理中通常不是这样


还要检查LMAX Disruptor或Real Logic Aeron的想法。

您检查过了吗?在没有同步的情况下实现最大吞吐量,但代价是可能过时的数据。然后是关于什么时候被哪个线程访问…谢谢。事实上,我正在使用LMAX Disruptor进行订单事件处理(从环形缓冲区读取单业务消费者线程)。正如您正确地说的,与静态数据缓存相关的更新不是CPU密集型的,也不是频繁的,这就是为什么我不喜欢使用单独的线程来维护这些数据。因此,其中一个选项是,我将静态数据更新也发送到环形缓冲区,并让我的主线程将它们存储在映射中,从而避免在订单事件处理期间进行任何线程间通信。@saurabh.in将更新发送到另一个环形缓冲区也是一种线程间通信,并且不是免费的(例如,缓冲区本身是一个内存和原子偏移)。但是,很难说成本与数据操作成本有什么不同-这对你的应用程序来说非常具体。因此,唯一正确的方法是做实验。测量性能,尝试一个更改,再次测量性能,然后选择更好的。实际上,我指的是将静态数据事件发送到用于订单事件的同一个环形缓冲区。这就是ay我的单个主线程将获得顺序和静态数据事件,并以不同的方式处理它们(对于静态数据,它将简单地将它们存储在hashmap中)因此,所有的事情都将由一个线程来处理。静态数据更新将很少,比如说10/天,所以我的主线程99%的时间将用于处理订单事件。另外,环缓冲区不涉及锁定,但我肯定会阅读您提到的原子偏移量。@saurabh.in我会投票支持sendi的这种方法将静态数据均衡到同一个缓冲区并维护简单的哈希映射。如果您执行共享并发映射,那么快速执行并不容易。例如,ConcurrentHashMap使用锁,因此您应该避免在事件流中使用此类数据结构。原子通常更快,但仍然会强制内存读取等,而单线程访问可能会使用CPU caches更积极。关于此应用程序中hazelcast的使用,我单独问了一个相关问题。如果您对此也有任何评论,那将非常好-缓存是静态的,不经常更改-可能一天10次。因此,我考虑让主线程在获取静态数据时在映射中维护它相关更新。从外部系统的传入事件中提取静态数据所需的小处理可以由单独的线程处理,然后该线程可以将准备存储的数据放入环形缓冲区(lmax disruptor),我的主线程可以读取该缓冲区并将其存储在hashmap中。