第一时间阅读最新文章

重要的一个接口和两个抽象类
在NIO中,有一个接口和两个抽象类是我们需要重点了解的,Channel,Buffer,Selector
1.Channel
Channel跟stream差不多,但是Channel是双向的(可以通过transferTo()或transferFrom()来改变数据的流向)
接口源码
public interface Channel extends Closeable {
//Channel接口只有两个抽象方法
//需要实现功能:检查是否开启
public boolean isOpen();
//需要实现功能:关闭通道
public void close() throws IOException;
}
主要抽象类
这几个类依然是没有实现,它们的实现都是类名后加上Impl,如果想深入研究的话,就去看实现类吧,我这里就只简单说明一下它们的抽象类
-
FileChannel
这个就是文件通道了,上面的代码中也有使用到,创建方式就不多说了。它的主要功能就是与文件进行数据传输 -
DatagramChannel
Datagram就是数据报的意思,学过网络编程的应该都知道,数据报通道就是可以通过UDP在网络上读取和写入数据,它的创建方法:
DatagramChannel ch = DatagramChannel.open();
-
SocketChannel
Socket就是套接字,套接字通道可以通过TCP在网络上读取和写入数据,它的创建方法:
SocketChannel ch = SocketChannel.open();
//使用它还需要绑定一个ip地址
-
ServerSocketChannel
ServerSocketChannel是服务器套接字通道,能够监听TCP的连接,在注册到selector后,当selector的迭代器遍历到相应的ServerSocketChannel时,它会根据SelectionKey获取到ServerSocketChannel创建的SocketChannel,然后进行操作
2.Buffer
Buffer就是在进行NIO时开辟缓冲区的对象
抽象类源码
内容太多了,简单易懂的我就跳过了
public abstract class Buffer {
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
// Invariants: mark = 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: ("+ mark + " > " + pos + ")");
this.mark = mark;
}
}
public final int capacity() {
return capacity;
}
public final int position() {
return position;
}
//这是重新定义position,如果大于limit或小于0则报错
//如果mark大于新的position,则丢去mark
public final Buffer position(int newPosition) {
if ((newPosition > limit) || (newPosition position) mark = -1;
return this;
}
public final int limit() {
return limit;
}
//重新定义limit,如果limit大于capacity或小于0,则报错
//如果position大于新的limit,则重新定位到limit
//如果mark大于新的limit,则丢弃
public final Buffer limit(int newLimit) {
if ((newLimit > capacity) || (newLimit limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
public final Buffer mark() {
mark = position;
return this;
}
//将position重新定位到mark上
public final Buffer reset() {
int m = mark;
if (m = limit)
throw new BufferUnderflowException();
return position++;
}
//将position后移nb个
final int nextGetIndex(int nb) {
if (limit - position = limit)
throw new BufferOverflowException();
return position++;
}
final int nextPutIndex(int nb) {
if (limit - position = limit))
throw new IndexOutOfBoundsException();
return i;
}
//检查是否能够将position定位到i+nb上
final int checkIndex(int i, int nb) {
if ((i limit - i))
throw new IndexOutOfBoundsException();
return i;
}
final int markValue() {
return mark;
}
//清空
final void truncate() {
mark = -1;
position = 0;
limit = 0;
capacity = 0;
}
final void discardMark() {
mark = -1;
}
//检查开始位置,长度,尺寸是否符合条件
static void checkBounds(int off, int len, int size) { // package-private
if ((off | len | (off + len) | (size - (off + len)))
主要抽象类
主要的抽象类有七个,ByteBuffer、CharBuffe、DoubleBuffer、FloatBuffer、 IntBuffer、 LongBuffer、 ShortBuffer,
分别对应基本数据类型: byte, char, double, float, int, long, short。
它们也都是没有实现的,它们的实现类就更加多样化了,这里就不展开讲述了,功能基本上都是差不多的,只是对应的数据类型不一样
3.Selector
Selector被称为选择器,也被称为多路复用器,是整个NIO中最核心的组件(个人觉得,不适用Selector就没有必要使用NIO了)
Channel能够通过register()把自己注册到Selector中并设置一个SelectionKey,然后Selector根据SelectionKey的迭代器不断的循环,当有符合某个key时,就可以进行操作了,操作时根据SelectionKey就可以获取到对应的Channel了。
graph LR
A[selector] --> B((channel))
A --> C((channel))
A --> D((channel))
A --> E((channel))
抽象类源码
public abstract class Selector implements Closeable {
protected Selector() { }
//这是通过SelectorProvider的内部静态对象provider创建一个Selector的实现类实例
//最后的实例对象是WindowsSelectorImpl的实例
public static Selector open() throws IOException {
return SelectorProvider.provider().openSelector();
}
public abstract boolean isOpen();
//需要实现的功能:
//返回一个通道的创建者
public abstract SelectorProvider provider();
//需要实现的功能:
//返回选择器的键集,该键集不能被修改
public abstract Set keys();
//需要实现的功能:
//返回选择器的键集,该键集可以被修改
public abstract Set selectedKeys();
//需要实现的功能:
//开始监听通道,如果没有通道是已经准备好的,就返回0
public abstract int selectNow() throws IOException;
//需要实现的功能:
//开始监听通道,设置一个超时时间
public abstract int select(long timeout)
throws IOException;
//需要实现的功能:
//开始监听通道
public abstract int select() throws IOException;
//需要实现的功能:
//唤醒那些阻塞在select方法上的线程
//在实现类WindowsSelectorImpl中,有一个线程数组,应该是唤醒这个数组中的线程
public abstract Selector wakeup();
public abstract void close() throws IOException;
}
最终的实现类是WindowsSelectorImpl
——————————————————————————————
你知道的越多,不知道的越多。
如果本文章内容有问题,请直接评论或者私信我。如果觉得写的还不错的话,点个赞也是对我的支持哦
未经允许,不得转载!