我正在编写一个简单的线程应用程序。线程只是消息使用者并处理它。但是,如果线程以某种方式被中断并且消息未完全处理,我想将其放回队列并让其他实例获取它。所以我必须像这样编码:
public void run()
{
Map<String, String> data = null;
try
{
while(true)
{
data = q.getData();
System.out.println(this+" Processing data: "+data);
// let others process some data :)
synchronized(this){
sendEmail(data);
data = null;
}
}
}
catch (InterruptedException e)
{
System.out.println(this+" thread is shuting down...");
if(null!=data)
q.add(data);
}
}
...谢谢
编辑:感谢您的回复。现在一切都很清楚了。我知道即使代码行在同步块中,如果它们中的任何一个都可以抛出InterruptedException,那么它只是意味着它们可以在那个时候被中断。行q.getData()将此线程进入“阻塞”状态(我在q.getData()中使用LinkedBlockedQueue)。此时,该线程可以被中断。
答案 0 :(得分:6)
线程在其他线程调用interrupt()
的任何时候都不会捕获InterruptedException
,该方法也不会神奇地阻止它正在做的事情。相反,该方法设置一个线程可以使用interrupted()
读取的标志。某些其他方法将检查此标志,并在设置时引发InterruptedException
。例如,Thread.sleep()
和许多等待外部资源的I / O操作抛出它。
有关详细信息,请参阅Java Thread Interrupts Tutorial。
答案 1 :(得分:4)
除了David Harkness的回答:您还不理解synchronized
关键字的含义。
Synchornized不是一种“原子”或“不间断”的块。
除了其他线程无法同时在同一对象(在您的情况下为this
)上输入同步块之外,Synchornized块不提供任何保证(+某些内存一致性保证在您的情况下无关紧要) )。
因此,在您的情况下使用synchornized
毫无意义,因为不需要保护data
免受其他线程的并发访问(同样,您正在同步this
,我不要不要认为其他线程会在同一个对象上同步。)
另见:
答案 2 :(得分:1)
忽略while(true)
将线程放入CPU循环......
如果sendMail
执行任何检查线程中断的事情,它将抛出一个中断的异常。所以你的问题的答案可能是一个坚实的是,线程可以在synchronized块中被中断,你将必须捕获异常并检查它。
也就是说,InterruptedException是一个经过检查的异常,因此在较低级别上没有搞怪的bug,sendMail应该表明它可以抛出InterruptedException。
答案 3 :(得分:0)
是
Java同步意味着当线程获取它时,没有其他线程可以访问同一个锁。
如果您不希望任何其他线程能够访问消息(或任何其他对象),请使用synchronized(message)
阻止。