你能把同步成本推到一个线程上吗?
Can you push synchronization costs onto one thread?
我有两个线程:主线程执行应用程序的主要处理,辅助线程从主线程接收数据批次并处理并将它们输出给用户、文件或通过网络。一般来说,数据的处理速度应该比产生数据的速度快得多。我想确保主线程永远不会等待辅助线程。辅助线程可以接受任何数量的开销、扩展缓冲区、重做工作等,唯一的 objective 是最大化主线程的性能。理想情况下,主线程根本不会 synchronize
。有什么方法可以将同步成本推到 Java 中的一个线程吗?
最简单的方法是
一个没有大小限制的 BlockingQueue (LinkedBlockingQueu) 作为通信将阻止你的主线程 'synchronization' 成本,如果你的意思是他们在发送数据时等待其他线程。
这是解决方案的概要:
主线程隔离工作了一段时间,把数据堆成一个集合;
当它生成了一个不错的批次时,它:
我。为自己创建一个新集合;
二。将已填满的集合放在一边,可供阅读线程拾取;
三。 CASes 这个集合到 AtomicReference
.
阅读线程轮询此 AtomicReference
以获取更新;
当它注意到它已被设置时,它会选择批处理,CASing null
到共享引用中,以便主线程知道它可以放入另一个集合。
这对主线程的协调成本可以忽略不计(每批只有一个 CAS 操作),假设在共享新批时引用总是已经 null
。
读取线程可能 运行 一个轮询共享引用的繁忙循环,每次读取 null
时都会休眠一小段时间。使线程休眠时间非常短的最佳技术是
LockSupport.parkNanos(1);
这通常会休眠大约 30 微秒,整个循环将消耗大约 2-3% CPU 的时间。当然,如果您想进一步缩短 CPU 时间,您可以使用更长的暂停时间。
请注意,使线程在等待集中等待的协调技术会给双方带来非常大的延迟,因此如果 1 毫秒的延迟对您来说是一个大问题,您应该远离它们。
我有两个线程:主线程执行应用程序的主要处理,辅助线程从主线程接收数据批次并处理并将它们输出给用户、文件或通过网络。一般来说,数据的处理速度应该比产生数据的速度快得多。我想确保主线程永远不会等待辅助线程。辅助线程可以接受任何数量的开销、扩展缓冲区、重做工作等,唯一的 objective 是最大化主线程的性能。理想情况下,主线程根本不会 synchronize
。有什么方法可以将同步成本推到 Java 中的一个线程吗?
最简单的方法是 一个没有大小限制的 BlockingQueue (LinkedBlockingQueu) 作为通信将阻止你的主线程 'synchronization' 成本,如果你的意思是他们在发送数据时等待其他线程。
这是解决方案的概要:
主线程隔离工作了一段时间,把数据堆成一个集合;
当它生成了一个不错的批次时,它:
我。为自己创建一个新集合;
二。将已填满的集合放在一边,可供阅读线程拾取;
三。 CASes 这个集合到
AtomicReference
.阅读线程轮询此
AtomicReference
以获取更新;当它注意到它已被设置时,它会选择批处理,CASing
null
到共享引用中,以便主线程知道它可以放入另一个集合。
这对主线程的协调成本可以忽略不计(每批只有一个 CAS 操作),假设在共享新批时引用总是已经 null
。
读取线程可能 运行 一个轮询共享引用的繁忙循环,每次读取 null
时都会休眠一小段时间。使线程休眠时间非常短的最佳技术是
LockSupport.parkNanos(1);
这通常会休眠大约 30 微秒,整个循环将消耗大约 2-3% CPU 的时间。当然,如果您想进一步缩短 CPU 时间,您可以使用更长的暂停时间。
请注意,使线程在等待集中等待的协调技术会给双方带来非常大的延迟,因此如果 1 毫秒的延迟对您来说是一个大问题,您应该远离它们。