中断等待用户输入的线程

中断等待用户输入的线程

本文介绍了中断等待用户输入的线程,然后退出应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个线程运行, userInputThread 等待用户从命令行输入, interrupterThread 试图中断 userInputThread 启动后1秒。显然你不能打断被 System.in 阻塞的线程。另一个答案建议在中断线程之前用 System.in.close()关闭 System.in 。但是当我运行下面的代码, userInputThread 永远不会中断,应用程序只是挂起而不关闭。

I have two threads running, userInputThread waits for user input from the command line and interrupterThread tries to interrupt userInputThread 1 sec after starting. Obviously you cannot interrupt a thread that is blocked by the System.in. Another answer suggests to close System.in with System.in.close() before interrupting a thread. But when I run the following code, the userInputThread never gets interrupted and the app just hangs without closing.

class InputInterruptionExample {

    private Thread userInputThread;
    private Thread interrupterThread;

    InputInterruptionExample() {
        this.userInputThread = new Thread(new UserInputThread());
        this.interrupterThread = new Thread(new InterrupterThread());
    }

    void startThreads() {
        this.userInputThread.start();
        this.interrupterThread.start();
    }
    private class UserInputThread implements Runnable {
        public void run() {
            try {
                System.out.println("enter your name: ");
                String userInput = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            } catch (IOException e) {
                System.out.println("Oops..somethign went wrong.");
                System.exit(1);
            }
        }
    }
    private class InterrupterThread implements Runnable {
        public void run() {
            try {
                sleep(1000);
                System.out.println("about to interrupt UserInputThread");
                System.in.close();
                userInputThread.interrupt();
                userInputThread.join();
                System.out.println("Successfully interrupted");
            } catch (InterruptedException e) {
            } catch (IOException ex) {
                System.out.println("Oops..somethign went wrong.");
                System.exit(1);
            }
        }
    }
    public static void main(String[] args) {
        InputInterruptionExample exampleApp = new InputInterruptionExample();
        exampleApp.startThreads();
    }
}

已经有一个类似的,但没有任何确定的答案。

There's already a similar question, but there aren't any definite answers.

推荐答案

这解决了这个问题:

class InputInterruptionExample {

    private UserInputThread userInputRunnable;
    private Thread userInputThread;
    private Thread interrupterThread;

    InputInterruptionExample() {
        this.userInputRunnable = new UserInputThread();
        this.userInputThread = new Thread(userInputRunnable);
        this.interrupterThread = new Thread(new InterrupterThread());
    }

    void startThreads() {
        this.userInputThread.start();
        this.interrupterThread.start();
    }
    private class UserInputThread implements Runnable {
        private InputStreamReader isr;
        private BufferedReader br;

        UserInputThread() {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
        }

        public void run() {
            try {
                System.out.println("enter your name: ");
                try{
                    String userInput = br.readLine();
                } catch(NullPointerException e) {}
            } catch (IOException e) {
                System.out.println("Oops..somethign went wrong.");
                System.exit(1);
            }
        }
        public void closeBufferdReader() {
            try {
                System.in.close();
            } catch (IOException e) {
                System.out.println("Oops..somethign went wrong in closeBufferdReader() method");
                System.exit(1);
            }
        }
    }
    private class InterrupterThread implements Runnable {
        public void run() {
            try {
                sleep(1000);
                userInputRunnable.closeBufferdReader();
                userInputThread.interrupt();
                userInputThread.join();
                System.out.println("Successfully interrupted");
            } catch (InterruptedException e) {}
        }
    }
    public static void main(String[] args) {
        InputInterruptionExample exampleApp = new InputInterruptionExample();
        exampleApp.startThreads();
    }
}

更新:当BufferedReader以这种方式拆分时工作:

Update: This only works when BufferedReader is split up this way:

InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String userInput = br.readLine();

由于某种原因,当readLine()结构写为oneliner :

For some reason the interruption does not seem to work when the readLine() structure is written as a oneliner:

this.userInput = (new BufferedReader(new InputStreamReader(System.in))).readLine();

因此,虽然可以中断BufferedReader结构中的线程,以读取用户的输入。

So while it is possible to interrupt the thread in the split-up BufferedReader structure, it is now impossible to read user's input.

如果有人可以显示一种方式来获取用户输入,以及当用户没有及时提供任何输入时中断UserInputThread (当中断器正在休眠时),请执行。

If someone could show a way to be able to get user input as well as interrupt the UserInputThread when the user doesn't provide any input in time (while interrupter is sleeping), please do.

这篇关于中断等待用户输入的线程,然后退出应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 06:58