У меня есть основной вопрос о том, как 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);
}
}
Использование сервиса executor: 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();
}
}