Я знаю, что Callable позволяет вернуть значение или исключить исключение, тогда как Runnable этого не делает. Этот вопрос заключается не в разнице между двумя интерфейсами, а в последовательном возврате значений в следующем коде.Вызываемое последовательное выполнение
Пожалуйста, взгляните на следующий сегмент кода.
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<String>> futureList = new ArrayList<Future<String>>();
for (int i=0;i<10;i++) {
Runner runner = new Runner(i);
Future<String> future = executorService.submit(runner);
futureList.add(future);
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
for (Future<String> integerFuture : futureList) {
System.out.println("Returned value is : " + integerFuture.get());
}
Класс Runner для этого кода приведен ниже.
public class Runner implements Callable<String> {
private int id;
public Runner(Integer id) {
this.id = id;
}
@Override
public String call() throws Exception {
Random randomWait = new Random();
Thread.sleep(randomWait.nextInt(5)*1000);
Random random = new Random();
int randomInt = random.nextInt(100);
return id + " - " + randomInt;
}
}
Приведенный выше код всегда обеспечивает последовательный ответ, несмотря на то, что выполняемые им потоки могут спать в разные секунды.
Returned value is : 0 - 19
Returned value is : 1 - 88
Returned value is : 2 - 99
........
Returned value is : 9 - 42
Но для сравнения следующий сегмент кода обеспечивает более значимый отклик, так как потоки спят в разные периоды времени.
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i=0;i<10;i++) {
Runner runner = new Runner(i);
executorService.submit(runner);
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
Ниже представлен класс бегунов для сегмента. класса Runner общественности реализует Runnable {
private int id;
public Runner(Integer id) {
this.id = id;
}
@Override
public void run() {
Random randomWait = new Random();
try {
Thread.sleep(randomWait.nextInt(5)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Runner : " + id + " Finished.");
}
}
Как и следовало ожидать ответ этого потока является дискриминационным последовательным.
Runner : 5 Finished.
Runner : 9 Finished.
Runner : 1 Finished.
Runner : 3 Finished.
........
Так что мой вопрос в том, почему сегмент кода кулака с фьючерсами и отзывной ответ всегда последовательны? Мне кажется, что основной поток ждет до конца выполнения всех потоков и обеспечивает последовательный вывод. Но об этом не упоминается в джавадоке. Если бы ответ был чем-то наподобие второго, я мог бы это понять.
Предположим, я хотел получить возвращаемые значения в зависимости от времени выполнения, как я мог это сделать? Некоторая идея была бы признательна. Спасибо за ваше время. –
'long start = System.nanoTime(); ... обычный код ...; return System.nanoTime() - start; ' –