ThreadPoolExecutor线程池中的线程发生异常时

当ThreadPoolExecutor中的线程发生异常时,该线程会被回收并重新创建。异常不会阻断线程池的执行,其他任务仍会继续运行。通过使用ExecutorService的submit方法和Callable接口,可以捕获并处理内部线程的异常情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结论:发生异常的线程被回收,重新填充一个新的线程
证明:

		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();
		}

(好吧,依然很水)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值