在多个线程中使用Java.io.Console.writer()方法

时间:2014-07-01 22:59:16

标签: java multithreading

在多个线程中使用console.writer()时出现意外行为。在下面的例子中,当程序启动时,我产生了第二个线程,它应该打印到控制台“模拟错误”。每一秒。然后当你输入类似“获取状态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();
    }

}

相反发生的事情是在第一次打印“模拟错误”之后,只有在输入“获取状态9999”等模式时才会再次打印。这是两个完全不同的线程,具有不同的行为。为什么另一个线程仅在主线程获得“get status 9999”之类的输入时打印“模拟错误”。另一个线程应该每秒打印“模拟错误”,而不管主线程中发生了什么。

1 个答案:

答案 0 :(得分:0)

其原因是readLine()锁定了Console对象,因此任何其他尝试在其上写入的线程都会等待锁定为空闲。

查看Console

的文档

来自docs的引用:

  

读取和写入操作是同步的,以保证原子   完成关键业务;因此调用方法   readLine(),readPassword(),format(),printf()以及read,   对reader()和。返回的对象进行格式化和写操作   writer()可能在多线程场景中阻塞