Java nio基本知识2:selector/FileLock

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
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值