跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 因为 System.in.read()而阻塞的线程,无法通过 System.in.close()唤醒?
未分類
18 7 月 2020

因为 System.in.read()而阻塞的线程,无法通过 System.in.close()唤醒?

因为 System.in.read()而阻塞的线程,无法通过 System.in.close()唤醒?

資深大佬 : amiwrong123 25

这个程序想说明,因同步 IO 资源而阻塞的线程,可以通过关闭 IO 资源而停止阻塞。

//: concurrency/CloseResource.java // Interrupting a blocked task by // closing the underlying resource. // {RunByHand} import java.net.*; import java.util.concurrent.*; import java.io.*; import static net.mindview.util.Print.*;  class IOBlocked implements Runnable {     private InputStream in;     public IOBlocked(InputStream is) { in = is; }     public void run() {         try {             print("Waiting for read():");             in.read();         } catch(Exception e) {             e.printStackTrace();  //这句是我加的             if(Thread.currentThread().isInterrupted()) {                 print("Interrupted from blocked I/O");             } else {                 throw new RuntimeException(e);             }         }         print("Exiting IOBlocked.run()");     } }  public class CloseResource {     public static void main(String[] args) throws Exception {         ExecutorService exec = Executors.newCachedThreadPool();         ServerSocket server = new ServerSocket(8080);         InputStream socketInput =                 new Socket("localhost", 8080).getInputStream();         exec.execute(new IOBlocked(socketInput));         exec.execute(new IOBlocked(System.in));         TimeUnit.MILLISECONDS.sleep(100);         print("Shutting down all threads");         exec.shutdownNow();         TimeUnit.SECONDS.sleep(1);         print("Closing " + socketInput.getClass().getName());         socketInput.close(); // Releases blocked thread         TimeUnit.SECONDS.sleep(1);         print("Closing " + System.in.getClass().getName());         System.in.close(); // Releases blocked thread     } }/* Output: (85% match) Waiting for read(): Waiting for read(): Shutting down all threads Closing java.net.SocketInputStream Interrupted from blocked I/O Exiting IOBlocked.run() Closing java.io.BufferedInputStream Exiting IOBlocked.run()            //书中的打印结果就有这句,而我的没有 *///:~ 

打印结果:

Waiting for read(): Waiting for read(): Shutting down all threads Closing java.net.SocketInputStream java.net.SocketException: Socket closed  at java.net.SocketInputStream.socketRead0(Native Method)  at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)  at java.net.SocketInputStream.read(SocketInputStream.java:170)  at java.net.SocketInputStream.read(SocketInputStream.java:141)  at java.net.SocketInputStream.read(SocketInputStream.java:223)  at IOBlocked.run(Interrupting.java:24)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)  at java.lang.Thread.run(Thread.java:745) Interrupted from blocked I/O Exiting IOBlocked.run() Closing java.io.BufferedInputStream 

执行后,程序无法结束,从打印结果也可以看出,第二个线程还是处于运行中。这个例子来自 java 编程思想,书中说到,两个线程都会因为资源的关闭而结束.

所以,为什么因为 System.in.read()而阻塞的线程,无法通过 System.in.close()唤醒(可能是以抛出异常的方式)?明明书中都说可以,难道是 java 版本问题

大佬有話說 (6)

  • 資深大佬 : pursuer

    应该和操作系统实现有关,我用 C 在 windows 下测试了下,stdin 在 read 堵塞的状态下,close 也会堵塞

  • 資深大佬 : sioncheng

    看方法签名来解释?应该只是是 jvm 实现者的一些考虑和选择吧。毕竟操作系统层面的 socket api ( c/api ),也不是通过 exception 来表示 read 一个 closed 的 socket 。
    /**
    * Reads the next byte of data from the input stream. The value byte is
    * returned as an <code>int</code> in the range <code>0</code> to
    * <code>255</code>. If no byte is available because the end of the stream
    * has been reached, the value <code>-1</code> is returned. This method
    * blocks until input data is available, the end of the stream is detected,
    * or an exception is thrown.
    *
    * <p> A subclass must provide an implementation of this method.
    *
    * @return the next byte of data, or <code>-1</code> if the end of the
    * stream is reached.
    * @exception IOException if an I/O error occurs.
    */
    public abstract int read() throws IOException;

  • 主 資深大佬 : amiwrong123

    @pursuer
    这么说,有可能是哈。我还忘说自己的环境了,win10,jdk8.也许作者跑程序不是在 Windows 上跑的。

  • 主 資深大佬 : amiwrong123

    @sioncheng
    看了方法签名也是一脸懵啊,我都 System.in.close()了,那 System.in 这个 InputStream 此时感觉应该处于 the end of the stream is detected 的状态啊

  • 資深大佬 : sioncheng

    @amiwrong123,应该感知到了,你输出 System.in.read 返回到结果看看,应该是-1,它并不一定要通过异常告诉调用者吧。

  • 資深大佬 : johnj

    别用 IDE 执行,再试试

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具