我有两个线程:一个执行应用程序主处理的主线程,一个从主线程接收数据批处理的辅助线程,并处理它们,将它们输出到用户,文件或网络。通常,数据处理速度应比生成速度快得多。我想确保主线程永远不会等待辅助线程。辅助线程可以接受任何数量的开销,扩展缓冲区,重做工作等,唯一的目的是最大化主线程的性能。理想情况下,主线程永远不会synchronize
。有没有办法将同步成本推送到Java中的一个线程上?
答案 0 :(得分:1)
这是解决方案的概要:
主线程隔离工作一段时间,将数据堆积到集合中;
当它生成了一个不错的批处理时,它:
我。为自己创建一个新的集合;
II。将填满的集合放在一边,可供阅读线索选取;
III。将此集合转换为AtomicReference
。
阅读主题轮询此AtomicReference
以获取更新;
当它注意到它已被设置时,它会将批处理CAS null
加载到共享引用中,以便主线程知道它可以放入另一个集合。
主线程的协调成本可忽略不计(每批只有一个CAS操作),假设在共享新批次时引用始终为null
。
读取线程可以运行忙循环轮询共享引用,每次读取null
时都会休眠一小段时间。让线程在很短的时间内睡眠的最佳技术是
LockSupport.parkNanos(1);
通常会休眠30μs,整个循环将占用大约2-3%的CPU时间。当然,如果你想进一步降低CPU时间,你可以使用更长的暂停。
请注意,使线程在等待集中等待的协调技术会在双方都造成非常大的延迟,因此,如果1 ms延迟是您的主要考虑因素,则应远离它们。
答案 1 :(得分:0)
最简单的方法是 没有大小限制的BlockingQueue(LinkedBlockingQueu)作为通信会阻止你的主线程同步'如果你的意思是他们在发送数据时等待其他线程的话。