Java中的多线程 - 异步行为

时间:2017-03-16 15:33:07

标签: java multithreading concurrency java.util.concurrent concurrenthashmap

我正在使用multithreading处理来自文件的大量记录。每一行都是一条记录,我将每一行传递给单独的线程进行处理。问题是我必须收集这些处理过的记录,并在处理记录时生成一些更多的数据,然后在最终的数据收集中应用一些业务逻辑。我将一个共同的ConcurrentHashMap传递给所有线程以填充处理过的数据,当我通过visualVM对其进行调试时,我发现(截图如下)这些线程在等待中花费了大量时间而不是运行。我想这是因为在写入ConcurrentHashMap时一个线程获得了锁定。

有没有办法实现完全异步行为来实现我的目标?

visualVM snapshot

enter image description here

2 个答案:

答案 0 :(得分:1)

  

我发现这些线程在等待中花费了大量时间而不是运行。我想这是因为一个线程在写入ConcurrentHashMap时获取了锁。

这不是一个好的假设 - ConcurrentHashMap非常有效,旨在同时使用。即使它确实存在一些争论,但它远远不是我在这样的情况下看到的第一个地方。

这些线程在做什么其他工作? I / O是阻塞操作(如果读/写同一磁盘,则是同步的),如果多个线程正在进行I / O操作,那么这将影响吞吐量大于ConcurrentHashMap争用的吞吐量。< / p>

不要让每个线程都执行自己的I / O,而是考虑使用专用的I / O线程来读取磁盘所需的内容,并通过执行程序将该数据分发到专用的处理线程。然后,当期货完成时,I / O线程可以将结果写回磁盘(假设是需要的)。使用Java's async I/O framework也可以避免空闲线程。

答案 1 :(得分:0)

只是为了让每个人都知道工作线程中的等待是由于每个工作线程正在进行的db调用,并且池一次只有10个db连接可用。当我们增加工作线程的数量时,ConcurrentHashMaps确实有了等待,但这是非常小的延迟并且可以接受。

感谢大家的建议。