读书人

Java NIO Pipe的应用

发布时间: 2013-02-24 17:58:56 作者: rapoo

Java NIO Pipe的使用

?

? ??Java NIO Pipe是两个线程间的单道数据连接。一个Pipe有一个SourceChannel和一个SinkChannel。你可以将数据写入SinkChannel,这个数据可以从SourceChannel中读取。

? ? 下面是Pipe的一个内部结构图示:

Java NIO Pipe的应用

? ?

? ? 根据Javadoc的解释,不管一个线程是否向Pipe写入数据,它都会被阻塞,直到另外一个线程读取了该数据。另外SinkChannel只能写(write),SourceChannel只能读(read)

?

下面编写了一个读线程和写线程,它们共享一个Pipe。写线程往SinkChannel写入数据,读线程从SourceChannel读取数据。

package org.snake.pipe;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.Pipe;import java.nio.channels.Pipe.SinkChannel;import java.nio.channels.Pipe.SourceChannel;import java.util.concurrent.TimeUnit;/** * 读线程 */class Reader implements Runnable {private SourceChannel inChannel;ByteBuffer buf;public Reader(SourceChannel inChannel) {this.inChannel = inChannel;buf = ByteBuffer.allocate(48);}@Overridepublic void run() {while (true) {buf.clear();try {int readBytes = inChannel.read(buf);while (readBytes != -1) {buf.flip(); // 切换到读模式System.out.print("Reader:开始读数据");while (buf.hasRemaining()) {System.out.print((char) buf.get()); // 一次读一个字节}buf.clear();readBytes = inChannel.read(buf);}System.out.println();} catch (IOException e) {e.printStackTrace();}}}}/** * 写线程 */class Writer implements Runnable {private SinkChannel outChannel;private ByteBuffer buf;private int increment = 1;public Writer(SinkChannel outChannel) {this.outChannel = outChannel;buf = ByteBuffer.allocate(48);}@Overridepublic void run() {while (true) {try {TimeUnit.SECONDS.sleep(5); // 休眠5秒钟} catch (InterruptedException e1) {e1.printStackTrace();}buf.clear();String msg = "msg:" + increment++;buf.put(msg.getBytes());buf.flip();System.out.printf("%nWriter:开始写数据%s%n", msg);while (buf.hasRemaining()) {try {outChannel.write(buf);} catch (IOException e) {e.printStackTrace();}}}}}public class Main {public static void main(String[] args) throws IOException {Pipe pipe = Pipe.open();SourceChannel inChannel = pipe.source();SinkChannel outChannel = pipe.sink();Reader reader = new Reader(inChannel); // 读线程Writer writer = new Writer(outChannel); // 写线程new Thread(reader).start();new Thread(writer).start();}}

?下面是其中一部分输出:

Writer:开始写数据msg:1Reader:开始读数据msg:1Writer:开始写数据msg:2Reader:开始读数据msg:2Writer:开始写数据msg:3Reader:开始读数据msg:3Writer:开始写数据msg:4Reader:开始读数据msg:4...

?

1 楼 lazynote 19 小时前 想问下楼主,NIO PIPE在LINUX下的counterpart是什么? 2 楼 zjuttsw 18 小时前 lazynote 写道想问下楼主,NIO PIPE在LINUX下的counterpart是什么?
应该是unistd.h里的pipe(int fd[2])吧 3 楼 lazynote 16 小时前 zjuttsw 写道lazynote 写道想问下楼主,NIO PIPE在LINUX下的counterpart是什么?
应该是unistd.h里的pipe(int fd[2])吧
谢谢了。我最近也在学习NIO,觉得博主的博客写得不错,想再问些问题。

1 J2EE开发中都是使用了Tomcat、weblogic等服务器,不像C++那样一般都自己用epoll等实现一个连接服务器,那么J2EE中NIO能够在哪里应用呢?

2 我现在还是比较难从直觉上理解,为什么NIO要比多线程的处理要优秀。
多线程能使用多个CPU,而NIO只能使用一个CPU;
处理N个并发请求,用N个线程去处理,不是应该要比1一个线程要快吗?
还是在某些关键的地方没有理解到? 4 楼 zjuttsw 16 小时前 lazynote 写道zjuttsw 写道lazynote 写道想问下楼主,NIO PIPE在LINUX下的counterpart是什么?
应该是unistd.h里的pipe(int fd[2])吧
谢谢了。我最近也在学习NIO,觉得博主的博客写得不错,想再问些问题。

1 J2EE开发中都是使用了Tomcat、weblogic等服务器,不像C++那样一般都自己用epoll等实现一个连接服务器,那么J2EE中NIO能够在哪里应用呢?

2 我现在还是比较难从直觉上理解,为什么NIO要比多线程的处理要优秀。
多线程能使用多个CPU,而NIO只能使用一个CPU;
处理N个并发请求,用N个线程去处理,不是应该要比1一个线程要快吗?
还是在某些关键的地方没有理解到?
不好意思,我也刚开始学习NIO,只有一些肤浅的认识,有本Oreilly出版的java nio书写的比较好,你可以去看一下。

读书人网 >编程

热点推荐