【发布时间】:2015-01-12 07:54:39
【问题描述】:
我有一个关于 ExecutorService 如何在 Java 中工作的基本问题。
很难看出简单地创建Threads 以并行执行一些任务和将每个任务分配给ThreadPool 之间的区别。
ExecutorService 看起来也非常简单高效,所以我想知道为什么我们不一直使用它。
这只是一种方式比另一种更快地执行其工作的问题吗?
这里有两个非常简单的例子来说明这两种方式的区别:
使用执行器服务:Hello World(任务)
static class HelloTask implements Runnable {
String msg;
public HelloTask(String msg) {
this.msg = msg;
}
public void run() {
long id = Thread.currentThread().getId();
System.out.println(msg + " from thread:" + id);
}
}
使用执行器服务:Hello World(创建执行器,提交)
static class HelloTask {
public static void main(String[] args) {
int ntasks = 1000;
ExecutorService exs = Executors.newFixedThreadPool(4);
for (int i=0; i<ntasks; i++) {
HelloTask t = new HelloTask("Hello from task " + i);
exs.submit(t);
}
exs.shutdown();
}
}
下面展示了一个类似的例子,但扩展了 Callable 接口,你能告诉我两者之间的区别吗?在哪些情况下应该使用特定的而不是另一个?
使用执行器服务:计数器(任务)
static class HelloTaskRet implements Callable<Long> {
String msg;
public HelloTaskRet(String msg) {
this.msg = msg; }
public Long call() {
long tid = Thread.currentThread().getId();
System.out.println(msg + " from thread:" + tid);
return tid;
}
}
使用执行器服务:(创建、提交)
static class HelloTaskRet {
public static void main(String[] args) {
int ntasks = 1000;
ExecutorService exs = Executors.newFixedThreadPool(4);
Future<Long>[] futures = (Future<Long>[]) new Future[ntasks];
for (int i=0; i<ntasks; i++) {
HelloTaskRet t = new HelloTaskRet("Hello from task " + i);
futures[i] = exs.submit(t);
}
exs.shutdown();
}
}
【问题讨论】:
-
两个示例都使用
ExecutorService而不是创建新线程,所以我不确定在这种情况下您在比较两个示例之间的内容。您是否对何时使用Runnable以及何时使用Callable感到困惑?
标签: java multithreading executorservice