尝试中断并加入main时Java线程挂起

因此,我整整一天都在为此问题苦苦挣扎,并且查阅了一些线程教程和示例仍未能达到我想要的结果.

我有一个线程,其唯一的工作是轮询Strings的LinkedBlockingQueue,然后使用PrintWriter通过套接字将字符串传递给客户端.该功能运行良好,但是我现在尝试通过允许它在连接中断和重启时正常失败来增强它.为了完成此任务,我在线程上调用中断,然后加入线程,最终目的是重新创建Thread对象.不幸的是,线程挂起了join的调用,这必须意味着线程实际上从未成功死亡,但是我对为什么会这样感到困惑.下面的相关代码.

try {
    resultSetStreamer.interrupt();
    resultSetStreamer.join();
    logger.info("Streamer finished.");
} catch (InterruptedException e) {}

实际线程代码;

class ResultSetStreamer implements Runnable {

    GZIPOutputStream gzos = null;
    Socket clientSocket = null;

    @Override
    public void run() {

        try {
            logger.debug("Thread started.");

            // Blocks and waits for an external connection.
            clientSocket = serverSocket.accept();

            // Creates a compression stream using best possible compression
            // to the external connection.
            gzos = new GZIPOutputStream(clientSocket.getOutputStream()) {
                {
                    def.setLevel(compression);
                }
            };
            PrintWriter toClient = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(gzos), bufferSize), false);

            while (true) {
                if (Thread.interrupted()) {
                    throw new InterruptedException();
                }
                if (moreRowsToReceive || !dataBuffer.isEmpty()) {
                    // Synchronisation point.
                    String row = dataBuffer.poll(pollTime,
                            TimeUnit.MILLISECONDS);
                    if (row != null) {
                        toClient.println(row);
                        logger.trace("Current row: " + ++currentCount + ".");
                    }
                } else {
                    toClient.flush();
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                gzos.finish();
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        logger.debug("Thread finished.");
    }
}

要看的主要地方是while(true)循环,该循环应始终循环并检查线程是否已被中断,在这种情况下,它会抛出在底部捕获的异常以使线程死亡.我认为PrintWriter不应阻止代码的执行.任何帮助将非常感激.

解决方法:

JVM不会强制中断来终止线程.您需要确保代码调用的所有阻塞调用都支持中断.

例如,如果客户端未接收到数据,则输出缓冲区将填满,并且toClient.println()将阻塞,但是此调用不支持中断,因此调用.interrupt()不会终止它.

我建议添加更多调试日志,以确定确切的代码块在哪里.

上一篇:.Net 调式案例—实验1 假死(hang)复习回顾


下一篇:【LeetCode 37】解数独