selector是选择器,用来检查channel的状态,可以实现单线程管理多个channel。
通道和选择器之间的关系,是通过注册完成的,注册的时候需要指定监控通道的哪些操作。
监控状态
可读: SelectionKey.OP_READ
可写: SelectionKey.OP_WRITE
连接: SelectionKey.OP_CONNECT
接受: SelectionKey.OP_ACCEPT
多个操作都感兴趣,可以用int key = SelectionKey.OP_WRITE | SelectionKey.OP_ACCEPT
selector查询的不是通道操作,是某个操作的一种就绪状态
SelectionKey是选择键,selector不断去各个channel查询
selector 创建并绑定channel
public class io7 {
public static void main(String[] args) throws IOException {
//创建
Selector s = Selector.open();
//调用,调用的channel要非阻塞模式
//创建通道
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
//绑定链接
ssc.bind(new InetSocketAddress(9999));
//通道注册到selector
ssc.register(s, SelectionKey.OP_ACCEPT);
//查询就绪的通道操作
Set<SelectionKey> keys = s.selectedKeys();
//遍历
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()){
SelectionKey key = it.next();
if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
} else if (key.isConnectable()) {
// a connection was established with a remote server.
} else if (key.isReadable()) {
// a channel is ready for reading
} else if (key.isWritable()) {
// a channel is ready for writing
}
}
}
}
pipe
Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
public class io8 {
public static void main(String[] args) throws IOException {
//管道安排
Pipe pipe = Pipe.open();
//获取sink
Pipe.SinkChannel sinkChannel = pipe.sink();
ByteBuffer bf = ByteBuffer.allocate(1024);
bf.put("bbw".getBytes());
bf.flip();
sinkChannel.write(bf);
ByteBuffer bf2 = ByteBuffer.allocate(1024);
Pipe.SourceChannel sourceChannel = pipe.source();
sourceChannel.read(bf2);
sourceChannel.close();
sinkChannel.close();
}
}
FileLock
排他锁:一个线程吃独食
共享锁:一个线程享用,其他线程可以读
lock() //对整个文件加锁,默认为排它锁。
lock(long position, long size, booean shared) //自定义加锁方式。前 2 个参数
指定要加锁的部分(可以只对此文件的部分内容加锁),第三个参数值指定是否是共
享锁。
tryLock() //对整个文件加锁,默认为排它锁。
tryLock(long position, long size, booean shared) //自定义加锁方式。
如果指定为共享锁,则其它进程可读此文件,所有进程均不能写此文件,如果某进程
试图对此文件进行写操作,会抛出异常。
lock阻塞,tryLock非阻塞
public class io9 {
public static void main(String[] args) throws IOException {
ByteBuffer bf = ByteBuffer.wrap("bbw".getBytes());
Path p = Paths.get("D:\\ex.txt");
FileChannel fc= FileChannel.open(p, StandardOpenOption.WRITE,StandardOpenOption.APPEND);
fc.position(fc.size() - 1);
FileLock lock = fc.tryLock(0,Long.MAX_VALUE,false);
System.out.println("共享锁 shared: " + lock.isShared());
fc.write(bf);
fc.close(); // Releases the Lock
}
}
println("共享锁 shared: " + lock.isShared());
fc.write(bf);
fc.close(); // Releases the Lock
}
}