我正在使用ExecutorService
并阻止主程序一段时间,但我不想阻止主程序。
以下是代码:
public class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
System.out.println("Start 1");
Runnable task = new Runnable() {
public void run() {
System.out.println("Start 2");
try {
Thread.sleep(7000);
System.out.println("Start 5");
} catch (Exception e) {
}
}
};
System.out.println("Start 3");
// executor.execute(task);
Future future = executor.submit(task);
Object result = future.get(9, TimeUnit.SECONDS);
System.out.println("Start 4");
} catch (Exception e) {
} finally {
System.out.println("finally");
executor.shutdownNow();
}
}
}
输出:
Start 1
Start 3
Start 2
Start 5
Start 4
finally
目前除非线程完成执行,否则它不会打印Start 4
。我正在寻找的是一些机制,我们可以有一个超时,线程在后台运行,不会阻止主线程?
答案 0 :(得分:0)
您正在使用future.get(9, TimeUnit.SECONDS);
这将等待9秒,以便提交的线程完成。
如果您不需要主程序等待,也不需要线程返回任何内容,请使用executor.execute
调用。
这是更新的代码......
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
System.out.println("Start 1");
Runnable task = new Runnable() {
public void run() {
System.out.println("Start 2");
try {
Thread.sleep(7000);
System.out.println("Start 5");
}
catch (Exception e) {
}
}
};
System.out.println("Start 3");
executor.execute(task);
System.out.println("Start 4");
}
catch (Exception e) {
}
finally {
System.out.println("finally");
executor.shutdown();
}
}
答案 1 :(得分:0)
在打印Start 4
之前,您没有在当前代码中捕获超时异常,但是在“开始4”之后您正在捕获异常。线。因此,如果超时,您无法获得所需的输出。
更改您的代码
这
Object result = future.get(9, TimeUnit.SECONDS);
到
try {
Object result = future.get(9, TimeUnit.SECONDS);
} catch (CancellationException ce) {
System.out.println("CancellationException ");
} catch (ExecutionException ee) {
System.out.println("ExecutionException ");
} catch (InterruptedException ie) {
System.out.println("InterruptedException ");
Thread.currentThread().interrupt(); // ignore/reset
}
使用上述代码,无论Start 4
任务是否超时,您始终都会获得Future
。
有关详细信息,请参阅ThreadPoolExecutor文档页面中的afterExecute
方法。
关于主线程的阻止,目前您正在get()
上使用阻止Future
来电。如果您不想阻止主线程,请将ExecutorService更改为ExecutorCompletionService,并根据上页的文档使用新API。