简体   繁体   English

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

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

I am getting unexpected behavior when using console.writer() in multiple threads. 在多个线程中使用console.writer()时,我得到了意外的行为。 In the below example, when program starts, I spawn a second thread, which is supposed to print to the console "Simulating Error." 在下面的示例中,当程序启动时,我产生了第二个线程,该线程应该打印到控制台“ Simulating Error”。 every second. 每一秒。 Then the main thread is supposed to print to the console when you type something like "get status 9999": 然后,当您键入诸如“获取状态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". 而是在第一次打印“模拟错误”之后发生的情况,只有当您输入“获取状态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". 为什么仅当主线程获得“获取状态9999”之类的输入时,另一个线程才打印“模拟错误”。 The other thread should be printing "Simulating Error" every second regardless of what's going on in main thread. 另一个线程应该每秒打印“ Simulating Error”,而不管主线程中发生了什么。

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. 其原因是readLine()锁定Console对象,因此任何其他尝试在其上写入内容的线程都会等待该锁释放。

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 . 因此, 在多线程方案中 ,调用方法readLine(),readPassword(),format(),printf()以及对reader()和writer()返回的对象的读取,格式化和写入操作可能会阻塞

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM