【发布时间】:2019-03-08 10:03:53
【问题描述】:
在业务场景中,InterruptException 发生多次,有的在业务代码执行之前,有的在业务代码执行之后。如何处理InterruptException让我很困惑。
1. preBusiness 代码 semaphore.acquire()
try {
semaphore.acquire();
} catch (InterruptedException e) {
// do something
}
resObj = caller.stepTry();
semaphore.release();
-
发布企业代码
latch.await(),service.take().get()CompletionService<CallableResultBO> service = new ExecutorCompletionService<>(executor); CountDownLatch latch = new CountDownLatch(size); for (R callable : listCall){ callable.setCountParam(JdkThreadCountBO.buildByLatch(latch)); service.submit(callable); } try { latch.await(); } catch (InterruptedException e) { // do something } CallableResultBO[] resArr = new CallableResultBO[size]; for ( int i = 0; i < size; i++ ){ try { resArr[i] = service.take().get(); } catch (InterruptedException e) { // do something } catch (ExecutionException e) { // do something } }在实践中也发现了一些疑惑,我还在思考如何下结论。 一个线程不能随便打断。即使我们为线程设置了中断状态,它仍然可以获得CPU时间片。通常只有被 sleep() 方法阻塞的线程才能立即收到 InterruptedException,所以在睡眠中断任务的情况下,可以使用 try-catch 跳出任务。其他情况需要通过判断线程状态来判断是否需要跳出任务(Thread.interrupted()方法)。
另外,同步方法修改的代码在收到中断信号后不会立即中断。 ReentrantLock锁控件的同步代码可以被InterruptException打断。
【问题讨论】:
-
如果我有时间,我稍后会写一个全面的答案,但这个问题的最终答案是阅读 JCiP,Goetz 等人的 Java Concurrency in Practice 一书al,它详细地解决了这个问题。
-
感谢您的回复。我现在负责一个订单履行中心,经常写并发代码,经常遇到这个异常。这本书和讨论我都看过,但我的一些疑问还没有解决。虽然 Thread.sleep() 可以抛出这个异常,但它并不代表测试这个异常。与“深度java原理”相比,我需要从业务的角度来探索这个异常的最佳实践。
-
我不确定我是否理解您的要求,或者“深度 Java 原则”和“最佳实践”之间的区别。如果您不理解异常意味着,那么您编写的代码将不是最佳实践。
InterruptedException的意思是“我正在做一些涉及等待的事情,但是有人告诉我要快点停止等待,所以我没有完成涉及等待的事情”。处理InterruptedException的正确方法完全取决于涉及等待的情况以及谁可能中断了它。
标签: java exception concurrency