是否可以在run()的synchronized块中间中断线程?

时间:2011-02-28 08:05:31

标签: java multithreading

我正在编写一个简单的线程应用程序。线程只是消息使用者并处理它。但是,如果线程以某种方式被中断并且消息未完全处理,我想将其放回队列并让其他实例获取它。所以我必须像这样编码:

    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)。此时,该线程可以被中断。

4 个答案:

答案 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)阻止。

相关问题