美文网首页
Java Nio中的管道(pipe)示例(带注释)

Java Nio中的管道(pipe)示例(带注释)

作者: lazyM | 来源:发表于2020-06-23 10:36 被阅读0次

pipe 说明

管道可以被用来仅在同一个 Java 虚拟机内部传输数据。虽然有更加有效率的方式来在线程之间传输数据,但是使用管道的好处在于封装性。[1]

code

package com.nio.demo;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.Pipe;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Random;

public class PipeTest {

    public static void main(String[] args) throws Exception {
        // 创建一个可写通道,用于向控制台输出管道中的内容
        WritableByteChannel out = Channels.newChannel(System.out);
        //启动一个工作线程,向管道写入数据,返回值为管道读的一端
        ReadableByteChannel readableByteChannel = startWorker(10);
        //创建一个缓冲区,用于接收管道中的数据
        ByteBuffer buffer = ByteBuffer.allocate(100);
        //如果工作线程中的管道一端不关闭,这个地方会一直阻塞在这里,即使没有数据传输
        while(readableByteChannel.read(buffer)>=0) {
            //将缓冲区翻转成一个准备读出元素的释放状态
            buffer.flip();
            //输出到控制台
            out.write(buffer);
            //清空缓冲区
            buffer.clear();
        }

    }

    private static ReadableByteChannel startWorker(int reps) throws Exception {
        //打开一个管道
        Pipe pipe = Pipe.open();
        //创建工作线程,并打开管道写的一端(pipe.sink())
        Worker worker=new Worker(pipe.sink(), reps);
        worker.start();
        //返回管道读的一端
        return (pipe.source());
    }
    //工作线程类
    private static class Worker extends Thread {
        WritableByteChannel channel;
        private int reps;

        public Worker(WritableByteChannel channel, int reps) {
            this.channel = channel;
            this.reps = reps;
        }

        @Override
        public void run() {
            ByteBuffer buffer = ByteBuffer.allocate(100);
            try {
                for (int i = 0; i < reps; i++) {
                    doSomeWork(buffer);
                    while (channel.write(buffer) > 0) {
                        // empty
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        private String[] products = { "No good deed goes unpunished", "To be, or what?",
                "No matter where you go, there you are", "Just say \"Yo\"", "My karma ran over my dogma" };
        private Random rand = new Random();

        private void doSomeWork(ByteBuffer buffer) {
            int product = rand.nextInt(products.length);
            buffer.clear();
            buffer.put(products[product].getBytes());
            buffer.put("\r\n".getBytes());
            buffer.flip();
        }

    }

}


  1. 《Java Nio》

相关文章

网友评论

      本文标题:Java Nio中的管道(pipe)示例(带注释)

      本文链接:https://www.haomeiwen.com/subject/gxvcfktx.html