工作中遇到了一个线程中断异常,备忘记录一下。
主线程使用CompletableFuture开辟子线程进行了并行查询,但其中某个子线程执行时发生异常,没有捕获。
结果就在主线程等待所有子线程都执行完毕时报ExecutionException
从而对主线程打上了中断标识
而主线程随后又进行了数据查询,这时候从druid数据库连接池中获取数据连接会用到AQS中的可重入锁, 可重入锁会检查线程的中断标识,如果是中断,则抛出中断异常
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;public class TestInterrupt {public static void main(String[] args) throws InterruptedException {CompletableFuture[] asyncList = new CompletableFuture[]{CompletableFuture.runAsync(() -> {int a = 1/0;}),CompletableFuture.runAsync(() -> {int b = 1;})};try {CompletableFuture.allOf(asyncList).get(3, TimeUnit.SECONDS);} catch (InterruptedException | ExecutionException | TimeoutException e) {e.printStackTrace();Thread.currentThread().interrupt();}if(Thread.currentThread().isInterrupted()){//主线程被中断了throw new InterruptedException("主线程被中断了!");}}
}
执行结果:
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1928)
at com.util.TestStream.main(TestStream.java:35)
Caused by: java.lang.ArithmeticException: / by zero
at com.util.TestStream.lambda$main 0 ( T e s t S t r e a m . j a v a : 28 ) a t j a v a . u t i l . c o n c u r r e n t . C o m p l e t a b l e F u t u r e 0(TestStream.java:28) at java.util.concurrent.CompletableFuture 0(TestStream.java:28)atjava.util.concurrent.CompletableFutureAsyncRun.run(CompletableFuture.java:1640)
at java.util.concurrent.CompletableFuture A s y n c R u n . e x e c ( C o m p l e t a b l e F u t u r e . j a v a : 1632 ) a t j a v a . u t i l . c o n c u r r e n t . F o r k J o i n T a s k . d o E x e c ( F o r k J o i n T a s k . j a v a : 289 ) a t j a v a . u t i l . c o n c u r r e n t . F o r k J o i n P o o l AsyncRun.exec(CompletableFuture.java:1632) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool AsyncRun.exec(CompletableFuture.java:1632)atjava.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)atjava.util.concurrent.ForkJoinPoolWorkQueue.runTask(ForkJoinPool.java:1067)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1703)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:172)
Exception in thread “main” java.lang.InterruptedException: 主线程被中断了!
at com.util.TestStream.main(TestStream.java:43)