代码之家  ›  专栏  ›  技术社区  ›  vitaut

如何在Java中停止等待块读取操作的线程?

  •  19
  • vitaut  · 技术社区  · 14 年前

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

    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);
        }
    }
    

    哪里 in System.in . 我如何才能优雅地停止这样的线程?两个都没有结束 程序输入 ,也不使用 Thread.interrupt 似乎起作用了。

    7 回复  |  直到 14 年前
        1
  •  8
  •   Community CDub    8 年前

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

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

        2
  •  7
  •   Denis Tulskiy    14 年前

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

        3
  •  2
  •   Paolo    14 年前

    您可以使用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...
    
        4
  •  1
  •   Nans    13 年前

    我今天也遇到了同样的问题,我就是这样解决的,用 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
                }
            }
        }
    }
    
        5
  •  1
  •   Tim Cooper    13 年前

    在其他线程中关闭流是否安全? 对我有用。在这种情况下, in.read(...) 引发异常 SocketException .

        6
  •  0
  •   Andreas Dolk    14 年前

    如果要给用户一些时间输入数据(可能允许覆盖默认值或中断某些自动化进程),请先等待,并在暂停后检查可用的输入:

    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*/ }
    
        7
  •  -3
  •   asela38    14 年前

    您可以使用外部标志

    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); 
        } 
    }