NIO WindowsSelectorProvidorImpl

// 开启多路复用器
Selector selector = Selector.open();
 /**
     * Opens a selector.
     *
     * <p> The new selector is created by invoking the {@link
     * java.nio.channels.spi.SelectorProvider#openSelector openSelector} method
     * of the system-wide default {@link
     * java.nio.channels.spi.SelectorProvider} object.  </p>
     *
     * @return  A new selector
     *
     * @throws  IOException
     *          If an I/O error occurs
     */
    public static Selector open() throws IOException {
        return SelectorProvider.provider().openSelector();
    }
// windows下返回默认的WindowsSelectorProviderImpl的实例
// linux下内核版本2.6以前返回poll, 2.6以后返回epoll实例
public class WindowsSelectorProvider extends SelectorProviderImpl {
    public WindowsSelectorProvider() {
    }

    public AbstractSelector openSelector() throws IOException {
        return new WindowsSelectorImpl(this);
    }
}

WindowsSelectorProviderImpl构造器的实现:

final class WindowsSelectorImpl extends SelectorImpl  
{  
    private final int INIT_CAP = 8;//选择key集合,key包装集合初始化容量  
    private static final int MAX_SELECTABLE_FDS = 1024;//最大选择key数量  
    private SelectionKeyImpl channelArray[];//选择器关联通道集合  
    private PollArrayWrapper pollWrapper;//存放所有文件描述对象(选择key,唤醒管道的源与sink通道)的集合  
    private int totalChannels;//注册到选择的通道数量  
    private int threadsCount;//选择线程数  
    private final List threads = new ArrayList();//选择操作线程集合  
    private final Pipe wakeupPipe = Pipe.open();//唤醒等待选择操操的管道  
    private final int wakeupSourceFd;//唤醒管道源通道文件描述  
    private final int wakeupSinkFd;//唤醒管道sink通道文件描述  
    private Object closeLock;//选择器关闭同步锁  
    private final FdMap fdMap = new FdMap();//存放选择key文件描述与选择key映射关系的Map  
    //子选择器,主要从pollWrapper拉取读写选择key,并更新key通道的就绪操作事件集  
    private final SubSelector subSelector = new SubSelector();  
    private long timeout;//超时时间,从pollWrapper拉取文件描述的超时时间  
    private final Object interruptLock = new Object();//中断同步锁,在唤醒选择操作线程时,用于同步  
    private volatile boolean interruptTriggered;//是否唤醒等待选择操的线程  
    private final StartLock startLock = new StartLock();//选择操作开始锁  
    private final FinishLock finishLock = new FinishLock();//选择操作结束锁  
    private long updateCount;//已选择key,更新就绪操作事件计数器  
    static final boolean $assertionsDisabled = !sun/nio/ch/WindowsSelectorImpl.desiredAssertionStatus();  
    static   
    {  
        //加载nio,net资源库  
        Util.load();  
    }   
} 

WindowsSelectorImpl(SelectorProvider var1) throws IOException {
   // 调用父类AbstractSelector构造器初始化SelectorProvider
        super(var1);
   // 设置唤醒sourceFd和sinkFd
        this.wakeupSourceFd = ((SelChImpl)this.wakeupPipe.source()).getFDVal();
        SinkChannelImpl var2 = (SinkChannelImpl)this.wakeupPipe.sink();
        var2.sc.socket().setTcpNoDelay(true);
        this.wakeupSinkFd = var2.getFDVal();
        this.pollWrapper.addWakeupSocket(this.wakeupSourceFd, 0);
    }
开启sourceChannel和sinkChannel
private final Pipe wakeupPipe = Pipe.open();
    /**
     * Opens a pipe.
     *
     * <p> The new pipe is created by invoking the {@link
     * java.nio.channels.spi.SelectorProvider#openPipe openPipe} method of the
     * system-wide default {@link java.nio.channels.spi.SelectorProvider}
     * object.  </p>
     *
     * @return  A new pipe
     *
     * @throws  IOException
     *          If an I/O error occurs
     */
    public static Pipe open() throws IOException {
        return SelectorProvider.provider().openPipe();
    }
    public Pipe openPipe() throws IOException {
        return new PipeImpl(this);
    }
PipeImpl(SelectorProvider var1) throws IOException {
        try {
            AccessController.doPrivileged(new PipeImpl.Initializer(var1));
        } catch (PrivilegedActionException var3) {
            throw (IOException)var3.getCause();
        }
    }
// 在本地主机上建立两个channel,并利用一个随机产生的long进行验证
private class Initializer implements PrivilegedExceptionAction<Void> {
        private final SelectorProvider sp;

        private Initializer(SelectorProvider var2) {
            this.sp = var2;
        }

        public Void run() throws IOException {
            ServerSocketChannel var1 = null;
            SocketChannel var2 = null;
            SocketChannel var3 = null;

            try {
                InetAddress var4 = InetAddress.getByName("127.0.0.1");

                assert var4.isLoopbackAddress();

                var1 = ServerSocketChannel.open();
                var1.socket().bind(new InetSocketAddress(var4, 0));
                InetSocketAddress var20 = new InetSocketAddress(var4, var1.socket().getLocalPort());
                var2 = SocketChannel.open(var20);
                ByteBuffer var6 = ByteBuffer.allocate(8);
                long var7 = PipeImpl.rnd.nextLong();
                var6.putLong(var7).flip();
                var2.write(var6);

                while(true) {
                    var3 = var1.accept();
                    var6.clear();
                    var3.read(var6);
                    var6.rewind();
                    if (var6.getLong() == var7) {
                        PipeImpl.this.source = new SourceChannelImpl(this.sp, var2);
                        PipeImpl.this.sink = new SinkChannelImpl(this.sp, var3);
                        return null;
                    }

                    var3.close();
                }
            } catch (IOException var18) {
                try {
                    if (var2 != null) {
                        var2.close();
                    }

                    if (var3 != null) {
                        var3.close();
                    }
                } catch (IOException var17) {
                    ;
                }

                IOException var5 = new IOException("Unable to establish loopback connection");
                var5.initCause(var18);
                throw var5;
            } finally {
                try {
                    if (var1 != null) {
                        var1.close();
                    }
                } catch (IOException var16) {
                    ;
                }

            }
        }
    }
implRegister方法:

protected void implRegister(SelectionKeyImpl selectionkeyimpl)  
{  
    //同步关闭锁,以防在注册的过程中,选择器被关闭  
    synchronized(closeLock)  
    {  
        if(pollWrapper == null)  
            //文件描述包装集合为null,即选器已关闭  
            throw new ClosedSelectorException();  
        growIfNeeded();//  
        channelArray[totalChannels] = selectionkeyimpl;//添加到选择器通道集合  
        selectionkeyimpl.setIndex(totalChannels);//设置key在选择器通道集合的索引  
        fdMap.put(selectionkeyimpl);//添加选择key到文件描述fdMap  
        keys.add(selectionkeyimpl);//添加key到key集合  
     //将选择key添加到文件描述信息及关注操作事件包装集合pollWrapper  
        pollWrapper.addEntry(totalChannels, selectionkeyimpl);  
        totalChannels++;//通道计数器自增  
    }  
}  









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值