NIO的非阻塞式实现"/>
NIO的非阻塞式实现
首先解释一下阻塞和非阻塞
对于传统的BIO,线程在同一时间只能等待数据的发送和接收,在此期间不能做其他的事
用图来表示
所以对于这种io,我们应该使用多线程的方式完成io通信
多线程虽然能完成同时接收和发送,但是本质上也是多个阻塞的单线程,多个线程中某个陷入阻塞,该线程还是不能做其他的事,造成资源的浪费。
NIO非阻塞模式,将每一个用于传输数据的通道都注册到选择器上,选择器监控通道的io状况(读,写,连接,接收数据),当某个通道上某个请求的事件完全就绪的时候,选择器才会将该任务分配给服务端的一个或多个线程,其他情况服务器的线程可以做其他事情。
nio非阻塞模式代码实现:
客户端
//客户端@Testpublic void TestClient(){SocketChannel client=null;ByteBuffer buffer=null;try {//获取socket连接client = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));//切换非阻塞状态client.configureBlocking(false);//指定缓冲区buffer = ByteBuffer.allocate(1024);//从控制台读入数据,发送数据到服务端Scanner scanner = new Scanner(System.in);while (scanner.hasNext()){buffer.put(scanner.next().getBytes());//切换成读模式buffer.flip();client.write(buffer);buffer.clear();}}catch (Exception e){e.printStackTrace();}finally {try {if (client!=null){client.close();}} catch (IOException e) {e.printStackTrace();}}}
服务端
@Testpublic void TestServer() throws IOException {ServerSocketChannel server = ServerSocketChannel.open();//1.切换非阻塞模式server.configureBlocking(false);//2.绑定server.bind(new InetSocketAddress("127.0.0.1",9898));//3.获取选择器Selector selector = Selector.open();//4.将服务注册到选择器上,第二个参数式选择键selectionkey表示,有四个常量// (1)selectionkey.OP_READ 读操作 (2)selectionkey.OP_WRITE 写操作 (3)selectionkey.OP_CONNECT 连接操作 (4)selectionkey.OP_ACCEPT 接收操作server.register(selector, SelectionKey.OP_ACCEPT); //将读事件注册到选择器上//5.轮询式的获取选择器上已经准备就绪的事件while (selector.select()>0){//6.获取当前选择器中所有注册的“选择键”Set<SelectionKey> keys = selector.selectedKeys();Iterator<SelectionKey> iterator = keys.iterator();while (iterator.hasNext()){SelectionKey key = iterator.next();//7.判断什么事件准备就绪if (key.isAcceptable()){//8.如果是接收就绪,采取动作SocketChannel accept = server.accept();//9.切换非阻塞状态accept.configureBlocking(false);//10.将读事件注册到selector上accept.register(selector,SelectionKey.OP_READ);}else if (key.isReadable()){//11.获取当前选择器上“读状态”的通道SocketChannel channel =(SocketChannel) key.channel();//12.读取数据ByteBuffer buffer = ByteBuffer.allocate(1024);int len=0;while ((len=channel.read(buffer))>0){buffer.flip();String s = new String(buffer.array(), 0, len);System.out.println(s);buffer.clear();}}//执行完任务之后就要取消选择键 因为将acceptor也iterator.remove();}}}
更多推荐
NIO的非阻塞式实现
发布评论