Java 如何根据CPU内核调整线程?
我想用Java解决一个多线程的数学问题。我的数学问题可以分成几个工作单元,我想用几个线程来解决 我不希望有固定数量的线程在上面工作,而是希望有与CPU内核数量相匹配的线程数量。我的问题是,我无法在互联网上找到一个简单的教程。我所找到的只是带有固定线程的示例Java 如何根据CPU内核调整线程?,java,multithreading,cpu-cores,Java,Multithreading,Cpu Cores,我想用Java解决一个多线程的数学问题。我的数学问题可以分成几个工作单元,我想用几个线程来解决 我不希望有固定数量的线程在上面工作,而是希望有与CPU内核数量相匹配的线程数量。我的问题是,我无法在互联网上找到一个简单的教程。我所找到的只是带有固定线程的示例 如何做到这一点?您可以提供示例吗?在运行时类中,有一个名为availableProcessors()的方法。你可以用它来计算你有多少个CPU。由于您的程序受CPU限制,您可能希望(最多)每个可用CPU有一个线程。您可以使用静态运行时方法确定J
如何做到这一点?您可以提供示例吗?在运行时类中,有一个名为availableProcessors()的方法。你可以用它来计算你有多少个CPU。由于您的程序受CPU限制,您可能希望(最多)每个可用CPU有一个线程。您可以使用静态运行时方法确定Java虚拟机可用的进程数。一旦确定了可用处理器的数量,就创建该数量的线程并相应地分割工作 更新:为了进一步澄清,线程只是Java中的一个对象,因此您可以像创建任何其他对象一样创建它。假设调用上述方法,发现它返回2个处理器。令人惊叹的。现在,您可以创建一个循环来生成一个新线程,并为该线程拆分工作,然后触发该线程。下面是一些伪代码来演示我的意思:
int processors = Runtime.getRuntime().availableProcessors();
for(int i=0; i < processors; i++) {
Thread yourThread = new AThreadYouCreated();
// You may need to pass in parameters depending on what work you are doing and how you setup your thread.
yourThread.start();
}
int processors=Runtime.getRuntime().availableProcessors();
对于(int i=0;i<处理器;i++){
Thread yourThread=new athrreadyoucreated();
//您可能需要传入参数,这取决于您正在做的工作以及如何设置线程。
yourThread.start();
}
有关创建自己的线程的详细信息。此外,您可能还需要查看线程的创建。您可能还需要查看java.util.concurrent框架来了解这些内容。 比如:
ExecutorService e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// Do work using something like either
e.execute(new Runnable() {
public void run() {
// do one task
}
});
或
Future=pool.submit(new Callable()){
公共字符串调用()引发异常{
返回null;
}
});
future.get();//将阻止,直到结果可用
这比处理自己的线程池等要好得多。Doug Lea(并发包的作者)有一篇文章,可能与此相关:
Fork-Join框架已添加到JavaSE7中。以下是更多的参考资料:
布赖恩·戈茨的文章
标准方法是Runtime.getRuntime().availableProcessors()方法。 在大多数标准CPU上,您将在此处返回最佳线程计数(不是实际的CPU核心计数)。所以这就是你要找的 例如:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
不要忘记像这样关闭executor服务(否则您的程序将无法退出):
这里只是一个如何设置基于未来的机器翻译代码的简要概述(非主题,用于说明):
CompletionService CompletionService=
新执行人完成服务(服务);
ArrayList futures=新的ArrayList();
for(字符串computeMe:elementsToCompute){
futures.add(completionService.submit(newyourcallableimplementor(computeMe));
}
然后,您需要跟踪预期的结果数量,并按如下方式检索:
try {
int received = 0;
while (received < elementsToCompute.size()) {
Future<YourCallableImplementor> resultFuture = completionService.take();
YourCallableImplementor result = resultFuture.get();
received++;
}
} finally {
service.shutdown();
}
试试看{
接收到的int=0;
while(接收到
选项1:
从执行者
public static ExecutorService newWorkStealingPool()
使用所有可用的处理器作为其目标并行级别创建工作线程池
使用此API,您不需要将内核数传递给ExecutorService
此API的实现来自
选项2:
来自Executors
或其他newXXX构造函数的API,返回ExecutorService
public static ExecutorService newFixedThreadPool(int nThreads)
将nThreads替换为Runtime.getRuntime().availableProcessors()
选项3:
public ThreadPoolExecutor(int-corePoolSize,
int maximumPoolSize,
长时间,
时间单位,
阻塞队列(工作队列)
将Runtime.getRuntime().availableProcessors()
作为参数传递给maximumPoolSize
Hi Jason和Eric(我对两个答案都使用一条注释,因为它基本相同)。好的,这很好检查,但这将是第一部分。当我有核数时,我必须让线程和这个核数一样可变。我以前试过这个例子(德语!),它使用了一个固定线程。但我希望在双核环境中使用2核,在四核环境中使用4核,实现相同的编程。我不想手动更改它。这可能吗?THX!:)@Andreas-查看我对帖子的更新。我认为这将有助于澄清问题。嗨,达维茨,嗯,我以前不知道这一点,所以我会看看这个。它可以根据可用的cpu内核进行缩放?因为我看不出你们的例子。值得一提的是,Andreasjava.util.concurrent是高度可伸缩的。对于CPU受限的进程,具有可用处理器数量的固定大小的池通常是最佳的。这里的第一个例子就是你需要做的一切。正如在接受答案的第一条评论中所述,最好使用报告的“处理者”数量的一半,原因有二:1。如果使用超线程,则实际处理器数量为报告数量的一半,为2。它可以让系统的其他部分(操作系统和其他程序)发挥一定的处理能力。这基本上是正确的,但在销售英特尔“超线程”的处理器上,要注意性能。在四核上,这将返回8而不是4,但您的性能实际上可能会下降
try {
int received = 0;
while (received < elementsToCompute.size()) {
Future<YourCallableImplementor> resultFuture = completionService.take();
YourCallableImplementor result = resultFuture.get();
received++;
}
} finally {
service.shutdown();
}
public static ExecutorService newWorkStealingPool()
/**
* Creates a work-stealing thread pool using all
* {@link Runtime#availableProcessors available processors}
* as its target parallelism level.
* @return the newly created thread pool
* @see #newWorkStealingPool(int)
* @since 1.8
*/
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public static ExecutorService newFixedThreadPool(int nThreads)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)