无法在具有wait和notify的多线程环境中从Socket输入流中读取

时间:2010-01-29 15:22:42

标签: java multithreading sockets

我使用2个线程 - ReaderThread从Socket输入流读取,而WriterThread用于写入套接字输出流。当我只是写入流而不是从流中读取时,它们都工作正常。但当我也从输入流中读取程序不会进一步运行时,它会挂起。

下面是在WriterThread类中编写它的代码。

try{
        Scanner consoleReader = new Scanner(System.in);
        String inst="";
        PrintWriter writer = new PrintWriter(client.getOutputStream(),true);
        while(true){
                synchronized(response){


                    System.out.print("Enter something: ");
                    System.out.flush();

                    inst=consoleReader.nextLine();
                    System.out.println(inst);
                    instruction.setInstruction(inst);
                    if(!instruction.getInstruction().equals("")){

                        writer.print(instruction.getInstruction());
                        writer.flush();
                        response.notifyAll();   

                        if(instruction.getInstruction().equalsIgnoreCase("end")){
                            break;
                        }
                        response.wait();

                    }
                }//End of response sync
        }//End of while
        }catch(IOException ioex){
            System.out.println("IO Exception caught in Writer Thread");
        }catch(InterruptedException iex){
            System.out.println("Writer thread interrupted");
        } 

上面的代码 - 从命令行读取,使用“writer”对象将其写入套接字输出流。

以下是从ReaderThread类

中的流读取的代码
try{        
        Scanner reader = new Scanner(client.getInputStream());
        String txtRead="";
        outer:
        while(true){
            synchronized(response){
                response.wait();
                System.out.println("Reader Running");

                while(reader.hasNext()){ //Line-Beg
                    txtRead=reader.next();
                    System.out.println("Received: "+txtRead);
                    if(txtRead.equalsIgnoreCase("end")){
                        response.notifyAll();
                        break outer;
                    }
                }//End of reader while, Line-End

                response.notifyAll();
            }//End of response sync
        }//End of while
        }catch(IOException ioex){
            System.out.println("IOException caught in ReaderThread");
        }
        catch(InterruptedException iex){
                System.out.println("Interrupted ReaderThread");
        }  

上面的代码从Socket的输入流中读取。上面代码的问题是它在打印后无限期地等待 - “Reader Running”。但是当我将Line-Beg中的代码注释掉到Line-End时,它会正确执行,以便让其他WriterThread写入输出流。为什么会这样?

注意:“response”是用于同步的常见对象。一旦主方法完成执行,也将关闭“服务器套接字”。客户端套接字也是“C”套接字。

我没有看到使用notify()和wait()方法的问题。

1 个答案:

答案 0 :(得分:2)

reader.hasNext()阻塞response对象锁定,直到套接字输入流中有一些输入可用。这可以防止writer线程获取response锁并写入套接字输出流。为什么要在同一个锁上同步读写器线程?对我来说似乎没必要。