结论:发生异常的线程被回收,重新填充一个新的线程
证明:
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(() -> {
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().getId()+":a");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
pool.execute(() -> {
System.out.println(Thread.currentThread().getId()+":b");
throw new RuntimeException();
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
pool.execute(() -> {
System.out.println(Thread.currentThread().getId()+":c");
});
按照上面的代码分析,不抛出异常的情况下,打印b的线程执行完成后要接着打印c。下面是打印结果:
12:22
12:b
Exception in thread “pool-1-thread-2” java.lang.RuntimeException
at com.test.myThread.TestPool.lambda1(TestPool.java:20)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)atjava.util.concurrent.ThreadPoolExecutor1(TestPool.java:20) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor1(TestPool.java:20)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)atjava.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
13:c
11:a
将抛出异常的代码注掉之后,再在执行:
12:b
12:c
11:a
(最近太忙了,水一下)
前几天写的太水了,今天补充一点。
线程池中的线程执行任务发生异常,如何让外层线程感知?用pool.submit(),
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<?> f = pool.submit(() -> { //使用submit,并用Future接值
System.out.println(Thread.currentThread().getId()+":b");
throw new RuntimeException();
});
try {
f.get();//这个方法使外部线程阻塞,直到submit的线程执行完毕或异常退出。
System.out.println("bb");//这里不打印,因为f.get()获取到异常了
} catch (Exception e) {
e.printStackTrace();
}
外部线程获取内部线程的执行结果,方式1,使用submit方法的第二个参数接返回值:
ExecutorService pool = Executors.newFixedThreadPool(2);
Map<String,Object> m = new HashMap<>();//submit方法中第二个参数就是用来接返回值的
Future<Map<String,Object>> f = pool.submit(() -> {
m.put("ThreadId", Thread.currentThread().getId());
},m);
try {
Map<String,Object> m2 = f.get();
System.out.println(m);
} catch (Exception e) {
e.printStackTrace();
}
外部线程获取内部线程的执行结果,方式2,使用Callable
ExecutorService pool = Executors.newFixedThreadPool(2);
Map<String,Object> m = new HashMap<>();
Future<Map<String,Object>> f = pool.submit(new Callable<Map<String,Object>>() {
@Override
public Map<String,Object> call() throws Exception {
m.put("ThreadId", Thread.currentThread().getId());
return m;
}
});
try {
f.get();
System.out.println(m);
} catch (Exception e) {
e.printStackTrace();
}
(好吧,依然很水)