Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何根据CPU内核调整线程?_Java_Multithreading_Cpu Cores - Fatal编程技术网

Java 如何根据CPU内核调整线程?

Java 如何根据CPU内核调整线程?,java,multithreading,cpu-cores,Java,Multithreading,Cpu Cores,我想用Java解决一个多线程的数学问题。我的数学问题可以分成几个工作单元,我想用几个线程来解决 我不希望有固定数量的线程在上面工作,而是希望有与CPU内核数量相匹配的线程数量。我的问题是,我无法在互联网上找到一个简单的教程。我所找到的只是带有固定线程的示例 如何做到这一点?您可以提供示例吗?在运行时类中,有一个名为availableProcessors()的方法。你可以用它来计算你有多少个CPU。由于您的程序受CPU限制,您可能希望(最多)每个可用CPU有一个线程。您可以使用静态运行时方法确定J

我想用Java解决一个多线程的数学问题。我的数学问题可以分成几个工作单元,我想用几个线程来解决

我不希望有固定数量的线程在上面工作,而是希望有与CPU内核数量相匹配的线程数量。我的问题是,我无法在互联网上找到一个简单的教程。我所找到的只是带有固定线程的示例


如何做到这一点?您可以提供示例吗?

在运行时类中,有一个名为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)