用于I / O绑定和CPU繁重操作的Java线程同步

时间:2010-12-17 12:49:35

标签: java multithreading synchronization

任务是 - 需要通过一些CPU操作来处理多个I / O流(HTTP下载)。理想情况下,希望使用全带宽和CPU 100%。当然 - 繁重的CPU处理比互联网下载慢。未处理的数据可以缓存到磁盘。 ASF中是否有现有的Executor或其他提供此功能的组件?如果不是 - 实现这一目标的最佳方法是什么?考虑为Internet-To-DiskDisk-To-CPU-To-Disk操作设置2个线程池。

编辑:

我会澄清我的问题:

2个线程池:Internet-To-DiskDisk-To-CPU-To-Disk是生产者/消费者方法本身。问题是如何确保我为producersconsumers选择了正确的线索数量?相同的代码将在不同的盒子上同时工作,具有不同核心数和不同带宽的拱门。如何确保我选择了正确的线程数,以便消耗100%的带宽和100%的CPU?

4 个答案:

答案 0 :(得分:1)

假设CPU处理将成为系统的主要瓶颈,CPU处理的线程数应至少设置为可用的CPU或核心数。

I / O部分可能根本不会占用太多CPU,但您可能希望分配一些固定的少量线程池(等于或小于内核数)以防止多余的线程上下文切换同步I / O流。

如果CPU处理线程从头到尾并不总是使用100%的CPU,您也可以将CPU处理的线程数设置为略大于内核数的数字。例如,如果他们可以在处理过程中进行一些I / O或访问某些共享资源。

但与任何系统一样,理想的线程数将在很大程度上取决于程序的性质。您可以使用JVisual VM(与JDK捆绑在一起)等工具来分析程序中线程的使用方式,并尝试不同的线程设置变体。

答案 1 :(得分:0)

您可以使用producer-consumer来实现此目的。尽可能多地使用生产者和消费者来满足需求。

答案 2 :(得分:0)

如果您的CPU阶段比下载时间更密集,为什么不下载数据,因为您可以处理它。这样,您就可以拥有多个Internet-To-CPU-To-Disk进程。跳过一个阶段可能会更快,而且肯定会更简单。

答案 3 :(得分:0)

我会选择生产者 - 消费者体系结构:一个用于处理数据的线程池(由ExecutorService管理),以及一个或多个从Internet下载数据的线程。

要处理的数据将放入有界阻塞队列(例如:LinkedBlockingQueue),以便下载线程只在需要时(即,当计算线程能够处理新数据时)获取数据。此外,这种结构保证了线程安全和内存发布。