需要一个基于Java的可中断计时器线程

我有一个主程序,它在目标设备(智能手机)上运行脚本,并在while循环中等待stdout消息.然而,在这种特殊情况下,标准输出上的一些心跳消息可以间隔近45秒到1分钟.

就像是:

stream = device.runProgram(RESTORE_LOGS, new String[] {});
stream.flush();
String line = stream.readLine();
while (line.compareTo("") != 0) {
    reporter.commentOnJob(jobId, line);
    line = stream.readLine();
}    

因此,我希望能够在从stdout读取具有所需睡眠窗口的行后启动新的可中断线程.在能够读取新行时,我希望能够中断/停止(无法终止进程),处理stdout文本的换行符并重新启动进程.

事件我无法在计时器窗口中读取一行(比如说45secs)我想要一种方法来摆脱我的while循环.

我已经尝试过thread.run,thread.interrupt方法.但是无法杀死并开始新线程.

这是最好的出路还是我错过了一些明显的东西?

最佳答案 看起来System.in的实现在不同平台之间存在很大差异,特别是并不总是提供可中断性或异步关闭.

这是一种不依赖于这些功能的解决方法,但代价是无法正常清理;如果在超时到期之前未收到输入,则Consumer线程将保留在阻塞读取()中.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

class InterruptInput
{

  private static final String EOF = new String();

  private final SynchronousQueue<String> pipe = new SynchronousQueue<String>();

  private final BufferedReader input;

  private final long timeout;

  InterruptInput(BufferedReader input, long timeout)
  {
    this.input = input;
    this.timeout = timeout;
  }

  public static void main(String... argv)
    throws Exception
  {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    InterruptInput input = 
      new InterruptInput(in, 5000);
    input.read();
  }

  void read()
    throws InterruptedException
  {
    System.out.println("Enter lines of input (or empty line to terminate):");
    Thread t = new Consumer();
    t.start();
    while (true) {
      String line = pipe.poll(timeout, TimeUnit.MILLISECONDS);
      if (line == EOF)
        break;
      if (line == null) {
        System.out.println("Input timed-out.");
        t.interrupt();
        break;
      }
      System.out.println("[input]: " + line);
    }
  }

  private class Consumer
    extends Thread
  {

    Consumer()
    {
      setDaemon(true);
    }

    @Override
    public void run()
    {
      while (!Thread.interrupted()) {
        String line;
        try {
          line = input.readLine();
        }
        catch (IOException ex) {
          throw new RuntimeException(ex);
        }
        try {
          if ((line == null) || (line.length() == 0)) {
            pipe.put(EOF);
            break;
          }
          else {
            pipe.put(line);
          }
        }
        catch (InterruptedException ex) {
          break;
        }
      }
    }
  }

}
点赞