线程中断并不总是有效

时间:2014-09-08 10:58:19

标签: java multithreading

我有一个以固定间隔发送UDP数据包的线程。一段时间后,我从另一个线程调用interrupt(),我希望发送者线程在此之后完全完成。大多数情况下,发送方线程在收到中断后会完成。但是,在极少数情况下,发件人线程不会。你能帮我看一下我的线程代码中的错误吗?

try {
    DatagramSocket socket = null;
    Timber.d("Initialize the sender...");

    while (!Thread.currentThread().isInterrupted()) {
        try {
            Timber.d("Sending UDP broadcasts...");
            socket = new DatagramSocket();

            while (!Thread.currentThread().isInterrupted()) {
                String s = "hello";
                byte[] buffer = s.getBytes();
                DatagramPacket packet = new DatagramPacket(
                        buffer, buffer.length,
                        mBroadcastAddress, PORT);
                try {
                    if (BuildConfig.DEBUG)
                        Timber.d("[" + new DateTime().toLocalTime() + "] " +
                                "Send UDP packet");
                    socket.send(packet);
                } catch (IOException ioe) {
                    Timber.d(ioe, "IOException");
                }
                Thread.sleep(TIMEOUT_SLEEP);
            }
        } catch (SocketException se) {
            Timber.d(se, "Socket exception");
            break;
        } finally {
            if (socket != null)
                socket.close();
            socket = null;
        }
    }
} catch (InterruptedException ie) {
    Timber.d("The sender thread received interrupt request");
}

Timber.d("Finish the sender...");

2 个答案:

答案 0 :(得分:1)

我认为问题在于:

    } catch (IOException ioe) {
        Timber.d(ioe, "IOException");
    }

问题是IOException的一种子类型是...... InterruptedIOException。当抛出该异常时(响应中断),线程的interrupted标志被清除。现在它很不可能"此代码将在send调用中被中断。但如果确实如此,那么你将有效地吃掉#34;中断。

我认为您应该将上述内容更改为:

    } catch (InterruptedIOException ioe) {
        Thread.currentThread().interrupt();
    } catch (IOException ioe) {
        Timber.d(ioe, "IOException");
    }

此外,如果稍后要测试中断标志,你也会"吃"当你在片段末尾抓住InterruptedException时,你应该再次设置它......如上所述。

答案 1 :(得分:0)

正如我所看到的,在你的代码的某个部分,你正在吞咽interruptedException。在捕获到interruptedException之后恢复中断,不要吞下它。 这是恢复中断的方法 Thread.currentThread()中断();