【问题标题】:Java writing to a socket during a read causes deadlockJava 在读取期间写入套接字会导致死锁
【发布时间】:2015-06-28 20:47:29
【问题描述】:

我遇到了看起来像死锁的问题。

这是一个客户端/服务器应用程序。服务器为每个套接字提供一个读取线程和一个写入线程。

读取线程接受客户端命令,对其进行处理,将结果放入队列,写入线程将其取出并写出。

问题是如果读线程在 readLine() 上阻塞,而写线程调用 println() 它也阻塞了,那么整个事情就会挂起。提供了 Stacktrace,看起来 println() 试图锁定 readLine() 拥有的资源。

谁能帮忙?

简化示例:

读取线程:

Socket s;
public void run() {
    BufferedReader sin = new BufferedReader(
        new InputStreamReader(s.getInputStream()));
    while (true) {
        String line = sin.readLine();
        if (line == null) { break; }
        String response = "You sent us this: [" + line + "]";
        // add response to queue
    }
}

写线程:

Socket s;
public void run() {
        PrintStream sout = new PrintStream(s.getOutputStream(), true);
        while (true) {
            String toWrite = getFromQueue();
            sout.println(toWrite);
            removeFromQueue(toWrite);
        }
}

客户代码:

public static void main(String[] args) throws IOException {
    int portNumber = 51192;
    Socket s = new Socket("127.0.0.1", portNumber);
    String cmd = "ThisIsATest";
    PrintStream out = new PrintStream(s.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
        new InputStreamReader(s.getInputStream()));
    out.println(cmd);
    String result = in.readLine();
    s.close();
    System.out.println(result);
}

堆栈跟踪:http://pastebin.com/JnsHUFZn

此示例的完整代码:http://pastebin.com/8RcbxgUw

【问题讨论】:

    标签: java multithreading sockets


    【解决方案1】:

    您必须从SocketChannel 获得服务器端Socket。与此类套接字关联的流由Channels 类分配,它们表现出您描述的行为。堆栈跟踪证实了这一点。

    直接使用java.net.Socket,即在服务器代码的情况下通过java.net.ServerSocket。在阻塞模式下使用SocketChannelServerSocketChannel 没有任何优势。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      • 2022-01-12
      • 2022-01-25
      相关资源
      最近更新 更多