我想用Java中的多个线程解决数学问题。我的数学问题可以分为多个工作单元,我想通过几个线程来解决。
我不希望有固定数量的线程在工作,而是与CPU核心数量匹配的线程数量。我的问题是,为此我在互联网上找不到简单的教程。我发现的都是带有固定线程的示例。
如何才能做到这一点?你能提供例子吗?
我想用Java中的多个线程解决数学问题。我的数学问题可以分为多个工作单元,我想通过几个线程来解决。
我不希望有固定数量的线程在工作,而是与CPU核心数量匹配的线程数量。我的问题是,为此我在互联网上找不到简单的教程。我发现的都是带有固定线程的示例。
如何才能做到这一点?你能提供例子吗?
Answers:
您可以通过使用静态运行时方法,确定提供给Java虚拟机的进程数availableProcessors。确定可用处理器的数量后,请创建该数量的线程,并相应地拆分您的工作。
更新:为了进一步阐明,线程只是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();
}
您可能也想看看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:
来自的newWorkStealingPoolExecutors
public static ExecutorService newWorkStealingPool()
使用所有可用处理器作为目标并行度级别来创建工作窃取线程池。
使用此API,您无需将内核数传递给ExecutorService
。
通过grepcode实现此API
/**
* 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 other newXXX constructors
,返回ExecutorService
public static ExecutorService newFixedThreadPool(int nThreads)
将nThreads替换为 Runtime.getRuntime().availableProcessors()
选项3:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
Runtime.getRuntime().availableProcessors()
作为参数传递给maximumPoolSize
。
道格·李(Doug Lea)(并发软件包的作者)拥有与以下内容相关的本文:http : //gee.cs.oswego.edu/dl/papers/fj.pdf
Java SE 7中已添加了Fork Join框架。以下是更多参考:
http://www.ibm.com/developerworks/java/library/j-jtp11137/index.html Brian Goetz的文章
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
标准方法是Runtime.getRuntime()。availableProcessors()方法。在大多数标准CPU上,您将在此处返回最佳线程数(不是实际的CPU内核数)。因此,这就是您要寻找的。
例:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
不要忘记像这样关闭执行程序服务(否则您的程序将不会退出):
service.shutdown();
这里只是快速概述如何设置基于将来的MT代码(以主题为例,以示说明):
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最多拥有一个线程。