我不是一个优秀的java程序员,这只是我的爱好,但我渴望了解更多的普通内容。
我想解决java中多线程的数学问题。我的数学问题可以分成工作单元,我想在几个线程中解决。
但我不希望有一定数量的线程处理它,而是相应的线程数量与cpu核心量相对应。 我的问题是,我在互联网上找不到一个简单的教程。我发现的只是固定线程的例子。
那么你能帮助我找到一个好的tuturial链接或者能给我一个简单而好的例子吗?那真是太棒了:)。
答案 0 :(得分:109)
您可以使用静态运行时方法availableProcessors来确定Java虚拟机可用的进程数。一旦确定了可用的处理器数量,就创建该数量的线程并相应地拆分您的工作。
更新:为了进一步说明,Thread只是Java中的一个Object,因此您可以像创建任何其他对象一样创建它。所以,假设你调用上面的方法并发现它返回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();
}
有关创建自己的主题的更多信息,请head to this tutorial。此外,您可能需要查看Thread Pooling以创建线程。
答案 1 :(得分:62)
你可能也想看看这个东西的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
这比处理自己的线程池等要好得多。
答案 2 :(得分:7)
Fork SE框架已添加到Java SE 7.以下是更多参考资料:
http://www.ibm.com/developerworks/java/library/j-jtp11137/index.html Brian Goetz的文章
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
答案 3 :(得分:7)
选项1:
来自Executors
的public static ExecutorService newWorkStealingPool()
使用所有可用处理器作为目标并行级别创建工作窃取线程池。
使用此API,您无需将核心数传递给ExecutorService
。
/**
* 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
或other newXXX constructors
的 newFixedThreadPool API,返回ExecutorService
public static ExecutorService newFixedThreadPool(int nThreads)
用 Runtime.getRuntime().availableProcessors()
选项3:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
将Runtime.getRuntime().availableProcessors()
作为参数传递给maximumPoolSize
。
答案 4 :(得分:4)
标准方法是Runtime.getRuntime()。availableProcessors()方法。 在大多数标准CPU上,您将返回最佳线程数(这不是实际CPU核心数)。因此,这就是你要找的。 p>
示例:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
不要忘记关闭执行程序服务(或者程序不会退出):
service.shutdown();
这里只是简要介绍如何设置基于未来的MT代码(offtopic,用于说明):
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();
}
答案 5 :(得分:3)
在Runtime类上,有一个名为availableProcessors()的方法。您可以使用它来确定您拥有多少CPU。由于您的程序受CPU限制,因此您可能希望每个可用CPU(最多)有一个线程。