当前位置: 首页 > 知识库问答 >
问题:

当调用print方法时,printWrit卡住了

蒋寒
2023-03-14

这是一个线程,用于处理服务器端的输入和输出:

    public void run() {
        Thread currentThread = Thread.currentThread();
        while (!currentThread.isInterrupted()) {
            SocketChannel socketChannel = null;
            try {
                socketChannel = serverSocketChannel.accept();
                readFromSocket(socketChannel);
            } catch (ClosedByInterruptException e) {
                // closed due to interrupt
                connected = false;
            } catch (IOException e) {
                if (!isInterrupted()) {
                    e.printStackTrace();
                }
                connected = false;
            } finally {
                quietClose(socketChannel);
            }
        }
    }

    /**
     * Reads an message from socketChannel and executes
     * {@link AbstractServer#handleMessage(String)}. Initializes
     * {@link #writer} with the socketChannel.
     * 
     * @param socketChannel
     * @throws IOException
     */
    public void readFromSocket(SocketChannel socketChannel) throws IOException {
        reader = null;
        writer = null;
        try {
            reader = new BufferedReader(new InputStreamReader(socketChannel.socket().getInputStream()));

            if (writer == null) {
                writer = new PrintWriter(socketChannel.socket().getOutputStream(), true);
            }
            String message;
            while ((message = reader.readLine()) != null) {
                handleMessage(message);
            }
        } catch (ClosedByInterruptException e) {
            throw e;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            quietClose(reader);
            quietClose(writer);
        }
    }

如果我调用print方法,线程就会被阻塞。这意味着“之前”是打印出来的,但“之后”永远不会到达。printwriter的CheckError方法返回false!

    /**
     * Sends a message to the client.
     * 
     * @param message
     */
    public void sendMessage(final String message) {
        System.out.println("before");
        writer.print(message);
        System.out.println("after");
        writer.flush();
    }

它位于一个AbstractServer中,由两个不同的服务器使用。第一个以前就已经使用过了,而且一直都没有问题(现在仍然如此)。另一个是新的,导致了这个问题。对于每个初始化的连接(两个具有不同端口的本地主机),它肯定只有一个写入程序。

客户端数据获取程序如下所示:

protected void fetchDataFromSocket() {
    if (socketDataFetcher != null) {
        socketDataFetcher.interrupt();
    }

    socketDataFetcher = new Thread(new Runnable() {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    String message = socketConnection.readLine();
                    if (messageHandler != null) {
                        messageHandler.handleMessage(message);
                    }
                } catch (IOException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    });
    socketDataFetcher.start();
}

它和另一个几乎一样,只需要很少的改变,实际上不会导致问题。是什么原因导致打印作者这样做的?

编辑:如果我不在客户端启动socketDataFetcher,printwriter就不会被卡住!

共有1个答案

伍心水
2023-03-14

虽然我没有看到这些声明,但reader和writer对象(在readFromSocket()方法中引用)看起来可能是成员变量。我会担心读者和作者不是线程安全的。我会考虑删除这些成员变量,看看你是否仍然与作者有问题。

 类似资料:
  • Im在配置PrometheusMeterRegistry以从Geode集群获取度量时遇到问题。配置完endpoint之后,如果我运行curl命令来检查所配置的endpoint上的度量是否可用,http请求处理程序将卡在刮取函数上: 如您所见,此代码主要与https://micrometer.io/docs/registry/Prometheus中配置Prometheus注册表的示例相同 但是如果我

  • 我正在调试一个普通的Java应用程序,没有GUI,只是在出现问题时对主线程进行大量计算和~5次调用。基本上,它一直在局部变量表中显示“收集数据”。 以前有人遇到过这个问题吗?更改调试器是解决这个问题的唯一方法吗?

  • 问题内容: 我在一个教程中找到了这个示例。 当我运行此程序时,我的hs.size()值为2 ..,并且equals方法仅被调用一次。有人解释了我何时在HashSet中调用equal()方法 当上述程序中的equal方法调用时 问题答案: 您的代码将调用的唯一一次。另一次调用方法将是对的类。 此答案说明何时由和何时调用方法。摘录: HashSet利用哈希码来加快处理速度。假定彼此相等的两个对象将具有

  • 问题内容: 是否有一种方法可以使每次调用方法时都会被调用的“超级方法”,即使对于未定义的方法也是如此?有点像这样: 编辑- 细节:我有一个库,该库进行了很多更新,并且每次更新都变得晦涩难懂。为了简化我的工作流程,我正在使程序自动更新库(需要执行我想做的事情,我不会具体说明原因,但是我的程序可以与将来的更新一起使用)并且我有混淆映射与库一起下载时,我想制作一种例如称为的代理,然后在我调用它时,将获得

  • 在这种方法中,它会提示用户输入其保险房屋的价值。由于某种原因,当用户输入时,它会被卡住 这里是validateNumber() 当提示出现“请输入您房屋的保险价值”时,它将接受输入并继续。现在,它被卡住了

  • 在使用Quartz Scheduler 1.8.6版的应用程序中,当作业未完成时,我们遇到了一个触发器卡住的问题。 例如,我们有ssh调用或数据库查询的作业。如果这些作业挂起(因为ssh调用没有终止,或者select语句有一个表锁),那么我将无法再触发这些作业。触发器被卡住,直到我强制重新启动调度程序。 我已经试过了。中断(触发器)和调度程序。重新调度触发器()。我试着移除触发器并重新创建它。我已