在多个线程中使用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”之类的输入时打印“模拟错误”。另一个线程应该每秒打印“模拟错误”,而不管主线程中发生了什么。
答案 0 :(得分:0)
其原因是readLine()锁定了Console对象,因此任何其他尝试在其上写入的线程都会等待锁定为空闲。
查看Console
的文档来自docs的引用:
读取和写入操作是同步的,以保证原子 完成关键业务;因此调用方法 readLine(),readPassword(),format(),printf()以及read, 对reader()和。返回的对象进行格式化和写操作 writer()可能在多线程场景中阻塞。