Skip to content
Advertisement

Using Java.io.Console.writer() Method in multiple threads

I am getting unexpected behavior when using console.writer() in multiple threads. In the below example, when program starts, I spawn a second thread, which is supposed to print to the console “Simulating Error.” every second. Then the main thread is supposed to print to the console when you type something like “get status 9999”:

public class NewConsoleExample {
    private volatile boolean running=true;
    private Lock lock = new ReentrantLock();


    public void startService(){
        Console cnsl = null;

          try{
             cnsl = System.console();

             if (cnsl != null) {

                 while(running){
                     String input = cnsl.readLine("<console>: ");
                     String[] msg = input.split(" ");
                     if(msg.length == 3){
                         if(msg[0].equals("get")){
                             lock.lock();
                             cnsl.writer().println(input);
                             lock.unlock();
                         }
                     }

                 }

             }      
          }catch(Exception ex){
             ex.printStackTrace();      
          }
    }


    public void startThreadInterrupt(){
        Thread consoleInterrupt = new Thread(new Runnable(){
            public void run() {
                Console cnsl = null;

                try {
                    cnsl = System.console();
                    if (cnsl != null) {
                        while(running){
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            lock.lock();
                            cnsl.writer().println("Simulating Error.");
                            lock.unlock();
                        }
                    }
                } catch(Exception ex){
                     ex.printStackTrace();      
                }

            }           
        });
        consoleInterrupt.start();
    }

    public static void main(String[] args) {        
        NewConsoleExample console = new NewConsoleExample();
        console.startThreadInterrupt();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        console.startService();
    }

}

Instead what happens is after “Simulating Error” is printed the first time, it is only ever printed again when you enter a pattern like “get status 9999”. These are two entirely different threads with different behavior. Why is the other thread printing “Simulating Error” only when the main thread gets input like “get status 9999”. The other thread should be printing “Simulating Error” every second regardless of what’s going on in main thread.

Advertisement

Answer

Its cause the readLine() locks the Console object, so any other thread that tries to write on it waits for the lock to be free.

Check the docs for Console

Quote from docs:

Read and write operations are synchronized to guarantee the atomic completion of critical operations; therefore invoking methods readLine(), readPassword(), format(), printf() as well as the read, format and write operations on the objects returned by reader() and writer() may block in multithreaded scenarios.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement