如何在Java中阻止线程在阻塞读取操作中等待?

时间:2010-11-15 08:05:04

标签: java multithreading stream

我有一个执行以下代码的线程:

public void run() {
    try {
        int n = 0;
        byte[] buffer = new byte[4096];
        while ((n = in.read(buffer)) != -1) {
            out.write(buffer, 0, n);
            out.flush();
        }
    } catch (IOException e) {
        System.out.println(e);
    }
}

其中inSystem.in。我怎样才能优雅地停止这样的线程?关闭System.in和使用Thread.interrupt似乎都无效。

7 个答案:

答案 0 :(得分:8)

这是因为读取System.in(InputStream)是一个阻塞操作。

看这里Is it possible to read from a InputStream with a timeout?

答案 1 :(得分:7)

你偶然发现了一个9岁的bug,没有人愿意修理。他们说this bug report有一些解决方法。最有可能的是,你需要找到一些其他方法来设置超时(繁忙的等待似乎是不可避免的)。

答案 2 :(得分:2)

您可以使用available()方法(非阻塞)来检查是否有事先要读取的内容。

在伪java中:

//...
while(running)
{
    if(in.available() > 0)
    {
        n = in.read(buffer);
        //do stuff with the buffer
    }
    else
    {
        Thread.sleep(500);
    }
}
//when running set to false exit gracefully here...

答案 3 :(得分:1)

我今天遇到了同样的问题,这就是我使用in.ready()修复它的方法:

public void run() {
    String line;
    // Some code

    while(!Thread.currentThread().isInterrupted()){
        try {
            if (in.ready()) {
                line = in.readLine();
            } 
        } catch (Exception e) {
            try {
                Thread.currentThread().wait(500);
            } catch (InterruptedException e1) {
                // Do what we want when thread is interrupted
            }
        }
    }
}

答案 4 :(得分:1)

在其他帖子中关闭流是否安全? 这个对我有用。在这种情况下,in.read(...)会抛出异常SocketException

答案 5 :(得分:0)

如果您想给用户一些时间来输入数据 - 可能允许覆盖默认值或中断某些自动过程 - ,请先暂停并在暂停后检查可用输入:

System.out.println("Enter value+ENTER within 5 Seconds to override default value: ");
try{
  Thread.sleep(5000);
} catch {InterruptedException e){}

try{
  int bytes = System.in.available();
  if (bytes > 0) {
    System.out.println("Using user entered data ("+size+" bytes)");
  } else {
    System.out.println("Using default value"); 
  }
} catch(IOException e) { /*handle*/ }

答案 6 :(得分:-3)

您可以为此

使用外部标记
boolean flag = true;


public void run() { 
    try { 
        int n = 0; 
        byte[] buffer = new byte[4096]; 
        while ((n = in.read(buffer)) != -1 && flag) { 
            out.write(buffer, 0, n); 
            out.flush(); 
        } 
    } catch (IOException e) { 
        System.out.println(e); 
    } 
}