我想在Java中使用多线程来解决一个数学问题。我的数学问题可以分成多个工作单元,在多个线程中解决。
我不想固定线程数量,而是希望线程数量匹配CPU核心数量。我的问题是,我在互联网上找不到简单的教程。我找到的所有示例都使用了固定数量的线程。
这该怎么做?您能提供一些示例吗?
我想在Java中使用多线程来解决一个数学问题。我的数学问题可以分成多个工作单元,在多个线程中解决。
我不想固定线程数量,而是希望线程数量匹配CPU核心数量。我的问题是,我在互联网上找不到简单的教程。我找到的所有示例都使用了固定数量的线程。
这该怎么做?您能提供一些示例吗?
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();
}
你可能也想看看 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<String> future = pool.submit(new Callable<String>() {
public String call() throws Exception {
return null;
}
});
future.get(); // Will block till result available
这比自己处理线程池等要好得多。
选项1:
从Executors
中使用newWorkStealingPool
public static ExecutorService newWorkStealingPool()
使用所有可用处理器作为目标并行级别,创建一个工作窃取线程池。
通过此 API,您无需将核心数传递给 ExecutorService
。
此 API 的实现来自于 grepcode
/**
* 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);
}
选项2:
Executors类提供的newFixedThreadPool
API或其他newXXX构造函数
,可返回ExecutorService
。
public static ExecutorService newFixedThreadPool(int nThreads)
用Runtime.getRuntime().availableProcessors()
替换nThreads
选项3:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
将Runtime.getRuntime().availableProcessors()
作为参数传递给maximumPoolSize
。
标准的方法是使用Runtime.getRuntime().availableProcessors()。 在大多数标准CPU上,这将返回最佳线程数(实际上不是CPU核心数)。因此,这就是您要寻找的内容。
例如:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
不要忘记像这样关闭执行器服务(否则你的程序将无法退出):
service.shutdown();
这里只是简要概述如何设置基于未来的机器翻译代码(离题,作为说明):
CompletionService<YourCallableImplementor> completionService =
new ExecutorCompletionService<YourCallableImplementor>(service);
ArrayList<Future<YourCallableImplementor>> futures = new ArrayList<Future<YourCallableImplementor>>();
for (String computeMe : elementsToCompute) {
futures.add(completionService.submit(new YourCallableImplementor(computeMe)));
}
try {
int received = 0;
while (received < elementsToCompute.size()) {
Future<YourCallableImplementor> resultFuture = completionService.take();
YourCallableImplementor result = resultFuture.get();
received++;
}
} finally {
service.shutdown();
}
在Runtime类中,有一个名为availableProcessors()的方法。您可以使用它来确定您有多少个CPU。由于您的程序是CPU绑定的,您可能希望每个可用CPU最多只有一个线程。
newFixedThreadPool
,它的表现比availableProcessors
好得多。这是如何实现的?在超过可用CPU核心数量的线程上如何工作? - wilmol