views:

322

answers:

1

I am using 2 threads- ReaderThread for reading from the Socket input stream and the WriterThread for writing to the socket output stream. Both of them work fine when am just writing to the stream and not reading from the stream. But when am also Reading from the input stream the program doesn't run further, it hangs.

Below is the code which does the writing- Its in the WriterThread class.

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");
        } 

The above code- Reads from the command line, writes it to the socket outputstream using the "writer" object.

Below is the code which reads from the stream- Its in the ReaderThread class

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");
        }  

The above code does the reading from the Socket's input stream. The problem wit the above code is it waits indefinitely after printing- "Reader Running". But when i comment out the code from Line-Beg to Line-End it executes properly giving chance for the other WriterThread to write to the output stream. Why is it so?

Note: "response" is a common object which is being used for synchronization. Also am closing the "server socket" once the main method completed execution. Also the client socket is a "C" socket.

I dont see a problem with the notify() and wait() methods being used.

+2  A: 

reader.hasNext() blocks while holding the response object lock until some input is available in the socket input stream. This prevents the writer thread from taking the response lock and writing to the socket output stream. Why are you synchronizing the reader and writer threads on the same lock? It seems unnecessary to me.

Amir Moghimi
I tried sending some data on the Socket Input Stream but it wasn't working. Actually wat i thought was like this- writer writes to the socket's o/p stream and notifies the reader thread to start reading the data available. After reader finishes its readin it waits for the writer thread to write something. So one has got to block itself until other finishes its task.
sana
In fact, why are you synchronizing? What's the shared resource being protected?
helios
My idea was to block one action while the other's being performed. Like while reading the data the app shouldn't be writin anything and vice versa.
sana
You can read from the socket while writing into it at the same time. There is no need for synchronization. Try removing the synchronized block and wait/notify calls and everything should work fine.
Amir Moghimi
Thanks a lot. I was thinking that if both are performed simultaneously then some wrong or irrelevant data may be read.
sana