API笔记之java.nio.channels.SelectionKey

本文详细介绍了Java NIO中的SelectionKey类,包括其主要作用、构造方式、关键方法及属性。通过本文,读者可以了解到如何利用SelectionKey来管理SelectableChannel在Selector上的注册状态,并掌握如何设置和检查事件兴趣集合,以及如何利用附带对象进行额外的数据绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API笔记之java.nio.channels.SelectionKey

 

import java.nio.channels.SelectableChannel;
import java.nio.channels.Selector;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * A token representing the registration of a {@link SelectableChannel} with a
 * {@link Selector}.
 * 
 * A token representing the registration of a SelectableChannel with a Selector. 
 * 一个SelectoableChannel在Selector中注册之后就产生一个SelectionKey对象,表示我们对这个SelectoableChannel的什么事件感兴趣,当然
 * SelectionKey的interestOps是我们自己传进去的, 我们调用selector的selectedKey方法会返回被选中的SelectionKey集,通过这个key判断
 * 什么事件,然后通过channel()方法进行io操作
 */

public abstract class SelectionKey {
	/**
	 * 四种事件用一个int(intrestOps)变量表示(其实byte也够了?)
	 * 	bits: [0|1]	   [0|1]   [0|1]	[0|1] 
	 * means: accept  connect  write    read
	 * 想要哪几种事件,就对这些事件的值进行或运算,得出的就是intrestOps
	 *比如 interestOps = 2(0010),该key会被选中, 事件是write, 主线逻辑拿得到这个key对应的channel可以进行写操作
	 */
	/**
     * 当selector发现: 
     * 1.channel有数据可读
     * 2.channel has been remotely shut down for further reading(不能100%确定其意思,猜测是channel的读通道关闭)
     * 3.channel has an error pending,有错误待处理?
     * 时, selector就会把该key加到selected key set中
     */
    public static final int OP_READ = 1 << 0;

    /**
     *这三个和上面差不多
     */
    public static final int OP_WRITE = 1 << 2;
    public static final int OP_CONNECT = 1 << 3; // 这个只有SocketChannel才有
    public static final int OP_ACCEPT = 1 << 4; // 这个只有ServerSocketChannel才有

    /**
     * 不给外部new实例, 在SelectionKeyImpl中会开放这个构造方法给包内的lei使用
     */
    protected SelectionKey() { }

    /**
     * Returns the channel for which this key was created.  This method will
     * continue to return the channel even after the key is cancelled.
     */
    public abstract SelectableChannel channel();

    /**
     * Returns the selector for which this key was created.  This method will
     * continue to return the selector even after the key is cancelled.
     */
    public abstract Selector selector();

    /**
     * Tells whether or not this key is valid.
     *
     * 当key被创建开始就是valid的,直到以下情况发生:
     * 1.cancel()方法被调用
     * 2.它对应的channel的被close
     * 3.它对应的selector被close
     */
    public abstract boolean isValid();

    /**
     * Requests that the registration of this key's channel with its selector
     * be cancelled.  
     * 被调用后,该key就是invalid的了,会被加到对应的selector的cancelled key set中,当selector的下一次选择操作时, 
     * 该key就会被移除(selector的三种key set)
     */
    public abstract void cancel();

    /**
     * Retrieves this key's interest set.
     */
    public abstract int interestOps();

    /**
     * Sets this key's interest set to the given value.
     */
    public abstract SelectionKey interestOps(int ops);

    /**
     * Retrieves this key's ready-operation set.
     */
    public abstract int readyOps();

    /**
     * Tests whether this key's channel is ready for reading.
     */
    public final boolean isReadable() {
        return (readyOps() & OP_READ) != 0;
    }

    /**
     * Tests whether this key's channel is ready for writing.
     */
    public final boolean isWritable() {
        return (readyOps() & OP_WRITE) != 0;
    }

    /**
     * Tests whether this key's channel has either finished, or failed to
     * finish, its socket-connection operation.
     */
    public final boolean isConnectable() {
        return (readyOps() & OP_CONNECT) != 0;
    }

    /**
     * Tests whether this key's channel is ready to accept a new socket
     * connection.
     */
    public final boolean isAcceptable() {
        return (readyOps() & OP_ACCEPT) != 0;
    }
    /**
     * 绑定的对象
     */
    private volatile Object attachment = null;

    //原子性更新引用类型的变量
    private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
        attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
            SelectionKey.class, Object.class, "attachment"
        );

    /**
     * Attaches the given object to this key.
     */
    public final Object attach(Object ob) {
        return attachmentUpdater.getAndSet(this, ob);
    }

    /**
     * Retrieves the current attachment.
     */
    public final Object attachment() {
        return attachment;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值