Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在多线程中使用Java.io.Console.writer()方法_Java_Multithreading - Fatal编程技术网

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

在多线程中使用Java.io.Console.writer()方法,java,multithreading,Java,Multithreading,在多个线程中使用console.writer()时,我遇到意外行为。在下面的示例中,当程序启动时,我生成第二个线程,该线程应该每秒打印到控制台“Simulation Error”。然后,当您键入“GetStatus 9999”之类的内容时,主线程应该打印到控制台: public类新控制台示例{ private volatile boolean running=true; private Lock=new ReentrantLock(); 公共无效startService(){ 控制台cnsl=n

在多个线程中使用console.writer()时,我遇到意外行为。在下面的示例中,当程序启动时,我生成第二个线程,该线程应该每秒打印到控制台“Simulation Error”。然后,当您键入“GetStatus 9999”之类的内容时,主线程应该打印到控制台:

public类新控制台示例{
private volatile boolean running=true;
private Lock=new ReentrantLock();
公共无效startService(){
控制台cnsl=null;
试一试{
cnsl=System.console();
如果(cnsl!=null){
(跑步时){
字符串输入=cnsl.readLine(“:”);
字符串[]msg=input.split(“”);
如果(msg.length==3){
if(msg[0].equals(“get”)){
lock.lock();
cnsl.writer().println(输入);
lock.unlock();
}
}
}
}      
}捕获(例外情况除外){
例如printStackTrace();
}
}
public void startThreadInterrupt(){
线程控制台中断=新线程(新可运行(){
公开募捐{
控制台cnsl=null;
试一试{
cnsl=System.console();
如果(cnsl!=null){
(跑步时){
试一试{
睡眠(1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
lock.lock();
cnsl.writer().println(“模拟错误”);
lock.unlock();
}
}
}捕获(例外情况除外){
例如printStackTrace();
}
}           
});
consoleInterrupt.start();
}
公共静态void main(字符串[]args){
NewConsoleExample控制台=新建控制台Example();
console.startThreadInterrupt();
试一试{
《睡眠》(2000年);
}捕捉(中断异常e){
e、 printStackTrace();
}
console.startService();
}
}
相反,在第一次打印“Simulation Error”(模拟错误)之后,只有当您输入类似“get status 9999”的模式时,才会再次打印。这是两个行为完全不同的线程。为什么另一个线程仅在主线程获得“get status 9999”之类的输入时才打印“模拟错误”。另一个线程应该每秒打印一次“模拟错误”,而不管主线程中发生了什么。

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

检查文档是否有错误

引用文件:

读写操作是同步的,以保证原子 完成关键操作;因此调用方法 readLine()、readPassword()、format()、printf()以及读取, 对reader()返回的对象执行格式化和写入操作,以及 writer()在多线程情况下可能会阻塞


有了这些知识,就很难创建一个多线程控制台应用程序,当多个线程使用readline时,会有很多阻塞,从而无法实现多线程的目的。
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();
    }

}