我有点困惑,Future.get(超时)如何按照定义超时时间之后的异常定义,但在我的测试用例中没有发生。
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class CallableExample {
public static class WordLengthCallable implements Callable<String> {
private String word;
private long waiting;
public WordLengthCallable(String word, long waiting) {
this.word = word;
this.waiting = waiting;
}
public String call() throws InterruptedException {
Thread.sleep(waiting);
return word;
}
}
public static void main(String args[]) throws Exception {
args = new String[] { "i", "am", "in", "love" };
long[] waitArr = new long[] { 3000, 3440, 2500, 3000 };
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<String>> set = new LinkedHashSet<Future<String>>();
int i = 0;
for (String word : args) {
Callable<String> callable = new WordLengthCallable(word, waitArr[i++]);
Future<String> future = pool.submit(callable);
set.add(future);
}
String sum = "";
for (Future<String> future : set) {
try {
sum += future.get(2000, TimeUnit.MILLISECONDS) + ", ";
} catch (Exception e) {
}
}
System.out.print("Result : " + sum);
}
}
输出“am,in,”
它在更改数组中的等待时间(timeArr值)时表现不同。何时使用get with timeout?
答案 0 :(得分:2)
在你的for循环中,你等待第一个未来完成。这可能需要2000毫升。此时所有其他线程都将睡眠。因此,其他线程的所有值都小于2000毫。然后你再等2000毫升,或许未来等待回报。因此,两个或多个线程将成功。
在循环的每次迭代中,您将2000毫秒捐赠给另一个线程。只有当一个未来成功返回时,您才会向剩余的期货捐赠更少。如果您希望观察到所有期货失败,由于2000毫秒超时,您还必须并行处理它们。
如果您以这种方式更改某些代码:
Set<Callable<String>> tasks = new HashSet<>();
for (String word : args) {
tasks.add(new WordLengthCallable(word, waitArr[i++]));
}
List<Future<String>> futures = Executors.newFixedThreadPool(3)
.invokeAll(tasks, 2000, TimeUnit.MILLISECONDS);
由于等待时间:
,您应该注意到任何任务都不会成功3000, 3440, 2500, 3000
创建的每个Callable
,都大于2000。
答案 1 :(得分:1)
编辑:感谢@RQube警告我线程的执行顺序为3.线程将在1.之前完成.4。线程将在3.完成后开始而不是1.
首先,你的线程池大小为3.这意味着你的4. Future将等待3.完成。
让我们假设除了线程等待之外没有耗时的工作。执行将是这样的:
未来 - 3000毫秒等待时间 - 这会抛出超时异常但会继续运行,因为您没有在超时时终止它。所以你的4. Future还在等待一个线程完成。 总执行时间:2000ms
未来 - 1440毫秒等待,因为你已经等待2000毫秒 - 这将返回你在输出“am”中看到的。同样在2500ms标记3.未来将被执行4.未来将在2500ms标记处开始。 总执行时间:3440ms
未来 - 没有等待时间,因为我们已经等待3440ms,这将立即返回。 总执行时间:3440ms。
未来 - 2060毫秒等待时间结束,因为这已经开始于2500毫秒大关,并且在启动后940毫秒已经过去。这将在2000ms(等待2940ms)之后超时
正如你只能看到2.和3.当你调用get()但实际上所有这些都被执行时,期货将会返回。
对不起格式错误和任何错别字,因为我在手机上写作。