【发布时间】:2019-01-12 12:03:32
【问题描述】:
为了避免 XY 问题,我将解释上下文: 我正在控制台模式下做一个聊天应用程序。用户可以发送文本或文件。如果用户收到一个文件,控制台会打印“收到新文件!你想把它保存在哪里?:”。
现在的问题:
我的Main.java 中有一个while(true) 循环,我在其中询问用户他想做什么,例如“发送”以发送消息,或“会话”以打印与用户的对话。所以这个循环中有一个scanner.nextLine()。
我有一个线程listener.java 监听TCP 连接,当我在TCP 中接收到一个文件时,我想执行scanner.nextLine() 来询问用户“你想把它保存在哪里?”。
但我不能这样做,因为我的listener.java 和我的Main.java 干扰,两个扫描仪试图同时从同一流( System.in ) 收听。
我尝试了Multiple Scanners in Multiple Threads 此处指出的解决方案,但它不起作用。 我试图同步扫描仪,但似乎我的线程没有成功锁定扫描仪。 与可重入锁相同的结果...
我写了一段代码让你明白我在说什么,这不是我的实际代码,但它重现了我的问题,一个线程与 Main 同时执行 sc.nextLine()。
public static void main(String [] args) throws IOException, InterruptedException {
Scanner sc = new Scanner(System.in);
Thread tt = new Thread(new Runnable() {
@Override
public void run() {
try {
//The thread wait...
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
String test= "";
//Here i receive a file so i ask the user where he wants to save it...
synchronized (sc) {
System.out.print("New file received ! where do you want to save it ? ");
test = sc.nextLine();
}
System.out.println("File written : " + test);
}
});
tt.start();
System.out.print("Main blabla ? ");
String bb = "";
while(true) {
synchronized (sc) {
bb = sc.nextLine();
}
System.out.print("blabla : " + bb);
//Do actions.....
}
}
【问题讨论】:
-
从一个线程调用方法通知另一个,获取控制扫描仪打印的线程。您可以简单地使用阻塞逻辑或更复杂的异步逻辑来做到这一点。绝对不要尝试共享输入流 - 您很快就会遇到缓冲区问题。
-
但是“同步”关键字的目的不就是允许多个线程访问一个资源吗?我的意思是,这是为了它的设计,不是吗?为什么它在这种情况下不起作用?感谢您的回答
-
首先,no-synchronized是为了保证对共享资源的同步访问;明确禁止并发访问。但它不起作用的真正原因是
Scanner缓冲。没有多少神奇的语言关键字可以为您解决这个问题。
标签: java multithreading java.util.scanner bufferedreader synchronized