黑马程序员技术交流社区

标题: IO中管道流的问题 [打印本页]

作者: 无气打火机    时间: 2013-7-29 02:07
标题: IO中管道流的问题
本帖最后由 无气打火机 于 2013-7-29 18:26 编辑
  1. class Read implements Runnable {
  2.                         private PipedInputStream in;
  3.                         Read(PipedInputStream in) {
  4.                                 this.in = in;
  5.                         }
  6.                         public void run() {
  7.                                 try {
  8.                                         byte[] buf = new byte[1024];
  9.                                         int len = in.read(buf);
  10.                                         String s = new String(buf,0,len);
  11.                                         System.out.println(s);
  12.                                         in.close();
  13.                                 }
  14.                                 catch (IOException e) {
  15.                                         throw new RuntimeException("读取失败");
  16.                                 }
  17.                         }

  18.                 }
  19.                 class Write implements Runnable {
  20.                         private PipedOutputStream out;
  21.                         Write(PipedOutputStream out) {
  22.                                 this.out=out;
  23.                         }
  24.                         public void run() {
  25.                                 try {
  26.                                         out.write("piped lai la".getBytes());
  27.                                         out.close();
  28.                                 }
  29.                                 catch (IOException e) {
  30.                                         throw new RuntimeException("输出败");
  31.                                 }
  32.                         }
  33.                 }
  34.                 class PipedStreamDemo {
  35.                         public static void main(String[] args)throws IOException {
  36.                                 PipedInputStream  in  = new PipedInputStream();
  37.                                 PipedOutputStream out = new PipedOutputStream();
  38.                                 in.connect(out);

  39.                                 Read r = new Read(in);
  40.                                 Write w =new Write(out);
  41.                                 new Thread(r).start();
  42.                                 new Thread(w).start();
  43.                         }
  44.                 }
复制代码
这里使用了多线程,都说管道流是这边进那边出,现在使用多线程,如果输出那边抢到了执行权
但是还没有数据,为什么也能成功输出?????????
作者: の放下执著    时间: 2013-7-29 04:51
首先,要明白read()方法是一个阻塞式的方法,当没有读到数据时,就阻塞、等待,这时其他的线程就拿到了执行权。
在这个程序中,假如线程r先抢到了执行权,执行read()方法,阻塞、等待,这时w线程就拿到了执行权,就会执行Write类中的run()方法中的任务,执行到write()方法时,就会往PipeInputStream里面写入数据。当线程r再次获得了执行权后,执行read()方法,发现有数据,这时就读取数据,完成任务。

class Read implements Runnable {
                        private PipedInputStream in;
                        Read(PipedInputStream in) {
                                this.in = in;
                        }
                        public void run() {
                                try {
                                        byte[] buf = new byte[1024];

                                         System.out.println("读取数据前,还没有阻塞");//
                                        int len = in.read(buf);//阻塞式方法,当执行到这里时,假如发现PipedInputStream中没有数据可读,那么阻塞、等待。
                                                                      //这时就会唤醒另外一个线程w, 并执行write()方法,往PipedInputStream中写入数据。
                                         System.out.println("读取数据完成");//
                                        String s = new String(buf,0,len);
                                        System.out.println(s);
                                        in.close();
                                }
                                catch (IOException e) {
                                        throw new RuntimeException("读取失败");
                                }
                        }

                }
                class Write implements Runnable {
                        private PipedOutputStream out;
                        Write(PipedOutputStream out) {
                                this.out=out;
                        }
                        public void run() {
                                try {
                                         System.out.println("准备写入数据,休眠5秒");//
                                          Thread.sleep(5000);
                                        out.write("piped lai la".getBytes());//写入数据
                                        out.close();
                                }
                                catch (Exception e) {
                                        throw new RuntimeException("输出败");
                                }
                        }
                }
                class PipedStreamDemo {
                        public static void main(String[] args)throws IOException {
                                PipedInputStream  in  = new PipedInputStream();
                                PipedOutputStream out = new PipedOutputStream();
                                in.connect(out);//连接

                                Read r = new Read(in);
                                Write w =new Write(out);
                                new Thread(r).start();
                                new Thread(w).start();
                        }
                }
在关键处加上了打印语句,希望可以帮助理解。
作者: Hello_world_    时间: 2013-7-29 07:50
read()当没有读到数据时,便会阻塞、等待,  操作系统里面有详细的介绍可以看看,read方法是一个阻塞式的方法!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2