我使用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()方法的问题。
答案 0 :(得分:2)
reader.hasNext()
阻塞response
对象锁定,直到套接字输入流中有一些输入可用。这可以防止writer线程获取response
锁并写入套接字输出流。为什么要在同一个锁上同步读写器线程?对我来说似乎没必要。