【问题标题】:Interrupt a thread waiting for user input中断等待用户输入的线程
【发布时间】:2012-02-18 07:38:09
【问题描述】:
    public class InterruptedInput {

    public static void main(String[] args) {
        InputThread th=new InputThread();  //worker thread instantiated.
        th.start();  //worker thread start.
        try{
            Thread.sleep(5000);  //main thread sleep for 5 sec.
        }catch(InterruptedException ex){}
        th.interrupt();  //worker thread interrupted.
    }
}

class InputThread extends Thread{
    int sum;
    BufferedReader br;
    public void run(){
        br=new BufferedReader(new InputStreamReader(System.in));
        try{
            sum();
            sleep(10000);  //worker thread sleep for 10 sec.
        }catch(Exception ex){
            System.out.println("sum="+sum);
        }
    }

    public void sum(){
        try{
            while(!isInterrupted()){
                sum+=Integer.parseInt(br.readLine());
            }
        }catch(Exception ex){}
    }
}

在这个程序中,工作线程等待用户输入(这将是一个整数值)并求和直到主线程interrut()它。
但是当主线程 interrupt() worker thread 它在 I/O 上用于用户输入并且不会中断。

我想提出这个程序的输出是:
当程序执行时,用户必须在五秒后输入整数值。输入值的总和被打印出来,要么用户仍在输入值,要么等待 5 秒消失。结果将在第 5 秒后立即打印。

【问题讨论】:

  • 我相信您的问题是 br.readLine() 将在重新评估循环的布尔值之前执行。这意味着您必须在循环到期后输入 1 个数字
  • @jozefg:你是对的。你有什么解决办法吗?

标签: java multithreading


【解决方案1】:

好的,所以这段代码的问题在于语句br.readLine() 必须在检查循环条件之前执行。所以为了避免这种情况,我可能会有 3 个线程。

线程 1:

这将是主线程或父线程。在这个线程中,您只需数到 5,然后中断线程 2。

线程 2:

在这个线程中你将监视静态变量:count,然后打印它并在中断时中断线程 3。

线程 3:

这是您将获取输入并将输入传递给一个函数,该函数会将其添加到count。被打断时什么也不做。

如果您有任何问题,请告诉我。

【讨论】:

    【解决方案2】:

    由于 IO 是不可中断的,您可以 @Override InputThread 关闭输入流

    @Override
    public void interrupt(){
       try{ 
           this.br.close();
       }finally{
           super.interrupt();
       }
    }
    

    【讨论】:

    • 输出不符合预期。请检查上面的代码。
    • 您不应该在 sum() 方法中捕获并吞下 IOException。删除该 try/catch 并使用方法声明内联传播异常。
    • @John Vint:我在我的(现已删除)答案中遵循与您相同的直觉,即从主线程异步关闭 BufferedReader 并导致 IOException,但由于某种原因它没有似乎工作。对 br.close() 的调用无限期阻塞。
    【解决方案3】:

    另一种方法是允许随时打印计数。将以下内容添加到 InputThread 类:

    private AtomicInt count;
    
    public int getCount() {
       return count;
    }
    

    并让 main 方法打印计数:

        System.out.println("Sum:" + th.getCount());
    

    这将避免任何中断线程的需要。

    【讨论】:

    • 对不起!但我需要它使用interrupt()
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多