Pipe类的使用、SelectorProvider类的使用

Pipe.SinkChannel和Pipe.SourceChannel类的使用

Pipe.SinkChannel类标识Pipe的可写入结尾的通道:
在这里插入图片描述
Pipe.SourceChannel类标识Pipe的可读取结尾的通道:
在这里插入图片描述
创建Pipe.SinkChannel和Pipe.SourceChannel类的实例需要使用Pipe类。

管道由一对通道组成:一个可写人的sink通道和一个可读取的source通道。一旦将某些字节写人接收器通道,就可以按照与写人时完全相同的顺序从源通道中读取这些字节。

在另一个线程从管道中读取这些字节或先前已写人的字节之前,是否阻塞将该字节写人管道的线程是与系统相关的,因此是未指定的。很多管道实现都对接收器和源通道之间一定数量的字节进行缓冲,但是不应假定会进行这种缓冲。

public static void main(String[] args) {
        try {
            Pipe pipe = Pipe.open();
            Pipe.SinkChannel sinkChannel = pipe.sink();
            Pipe.SourceChannel sourceChannel = pipe.source();

            Thread t1 = new Thread(){
                @Override
                public void run() {
                    try {
                        Thread.sleep(1024);
                        for (int i = 0; i < 5; i++) {
                            sinkChannel.write(ByteBuffer.wrap(("我来自客户端A " + (i + 1) + "\r\n").getBytes()));
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            t1.start();

            Thread t2 = new Thread(){
                @Override
                public void run() {
                    try {
                        Thread.sleep(1024);
                        for (int i = 0; i < 5; i++) {
                            sinkChannel.write(ByteBuffer.wrap(("我来自客户端B " + (i + 1) + "\r\n").getBytes()));
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            t2.start();

            Thread.sleep(3000);
            sinkChannel.close();

            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            int readLength = sourceChannel.read(readBuffer);
            while (readLength != -1) {
                System.out.println(new String(readBuffer.array(), 0, readLength));
                readLength = sourceChannel.read(readBuffer);
            }
            sourceChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
我来自客户端A 1
我来自客户端A 2
我来自客户端B 1
我来自客户端B 2
我来自客户端B 3
我来自客户端A 3
我来自客户端B 4
我来自客户端A 4
我来自客户端B 5
我来自客户端A 5
SelectorProvider类的使用

SelectorProvider是用于选择器和可选择通道的服务提供者类。选择器提供者实现类是SelectorProvider类的一个子类,它具有零参数的构造方法,并实现了以下指定的抽象方法。给定的对Java虚拟机的调用维护了单个系统级的默认提供者实例,它由provider()方法返回。

第一次调用该方法将查找指定的默认提供者。系统级的默认提供者由DatagramChannel、Pipe 、Selector 、ServerSocketChannel 和SocketChannel类的静态open()方法使用。System.inheritedChannel)方法也使用它。除了默认提供者之外,程序还可以使用其他提供者,方法是通过实例化一个提供者,然后直接调用此类中定义的open()方法。
多个并发线程可安全地使用SelectorProvider类中的所有方法。

public static void main(String[] args) throws IOException {
        SelectorProvider provider = SelectorProvider.provider();
        System.out.println("provider=" + provider.getClass().getName());
        Selector selector = provider.openSelector();
        DatagramChannel datagramChannel1 = provider.openDatagramChannel();
        DatagramChannel datagramChannel2 = provider.openDatagramChannel(StandardProtocolFamily.INET);
        DatagramChannel datagramChannel3 = provider.openDatagramChannel(StandardProtocolFamily.INET6);
        Pipe pipe = provider.openPipe();
        ServerSocketChannel serverSocketChannel = provider.openServerSocketChannel();
        SocketChannel socketChannel = provider.openSocketChannel();
        //方法inheritedChannel()在源代码中返回的值就是null
        Channel channel = provider.inheritedChannel();

        System.out.println("openSelector()=" + selector.getClass().getName());
        System.out.println("openDatagramChannel()=" + datagramChannel1.getClass().getName());
        System.out.println("openDatagramChannel(StandardProtocalFamily.INET)=" + datagramChannel2.getClass().getName());

        System.out.println("openPipe()=" + pipe.getClass().getName());
        System.out.println("openServerSocketChannel()=" + socketChannel.getClass().getName());
        System.out.println("openSocketChannel()=" + socketChannel.getClass().getName());
        System.out.println("inheritedChannel()=" + channel);
    }
provider=sun.nio.ch.KQueueSelectorProvider
openSelector()=sun.nio.ch.KQueueSelectorImpl
openDatagramChannel()=sun.nio.ch.DatagramChannelImpl
openDatagramChannel(StandardProtocalFamily.INET)=sun.nio.ch.DatagramChannelImpl
openPipe()=sun.nio.ch.PipeImpl
openServerSocketChannel()=sun.nio.ch.SocketChannelImpl
openSocketChannel()=sun.nio.ch.SocketChannelImpl
inheritedChannel()=null
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值