如何处理不同线程中的不同扫描仪

时间:2019-01-12 12:03:33

标签: java multithreading java.util.scanner bufferedreader synchronized

为避免XY问题,我将解释上下文: 我正在控制台模式下进行聊天应用程序。用户可以发送文本或文件。如果用户收到文件,控制台将打印“收到新文件!要将文件保存在哪里?:”。

现在是问题所在: 我的while(true)中有一个Main.java循环,我在该循环中询问用户他想做什么,例如“发送”以发送消息,或“会话”以打印与用户的对话。因此,此循环中有一个scanner.nextLine()

我有一个线程listener.java,我在其中监听TCP连接,并且当我收到TCP中的文件时,我想执行一个scanner.nextLine()来询问用户“您要将它保存在哪里” ?”。 但是我无法执行此操作,因为我的listener.java和我的Main.java会干扰,两个扫描程序会尝试同时从同一流( System.in )进行监听。

我尝试了Multiple Scanners in Multiple Threads此处指示的解决方案,但无效。 我试图同步扫描仪,但似乎我的线程无法成功锁定扫描仪。 可重入锁的结果相同...

我写了一段代码来使您理解我的意思,这不是我的实际代码,但是它重现了我的问题,一个线程与Main同时执行sc.nextLine()。 / p>

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.....
    }
}

1 个答案:

答案 0 :(得分:0)

使用多个Scanner从单个流中读取感觉很脆弱。该应用程序将从用户交互功能的封装中受益,这种方式可以使流和扫描器无法直接被代码库的其他部分访问。该抽象既应实现命令循环,又应处理从外部传入的事件,例如接收文件。

接收事件需要适当地同步,理想情况下需要缓冲到队列中,以便在用户响应先前事件时可以接收新事件。总而言之,用户交互抽象将始终只做一件事-如果没有事件,则读取用户对下一个事件或下一个命令的响应。这样,将只有一个线程和Scanner专用于读取输入流。