文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java NIO就绪模式怎么实现

2023-06-17 12:20

关注

这篇文章主要介绍“Java NIO就绪模式怎么实现”,在日常操作中,相信很多人在Java NIO就绪模式怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java NIO就绪模式怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源的。

Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。

Java NIO出现不只是一个技术性能的提高,你会发现网络上到处在介绍它,因为它具有里程碑意义,从JDK1.4开始,Java开始提高性能相关的功能,从而使得Java在底层或者并行分布式计算等操作上已经可以和C或Perl等语言并驾齐驱。

Java NIO就绪模式怎么实现
图 1      类结构图

package cn.chenkangxian.nioconcurrent;  import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.util.LinkedList; import java.util.List;   public class SelectSocketsThreadPool extends SelectSockets {      private static final int MAX_THREADS = 5;     private ThreadPool pool = new ThreadPool(MAX_THREADS);           protected void readDataFromSocket(SelectionKey key) throws Exception {         WorkerThread worker = pool.getWorker();         if (worker == null) {             return;         worker.serviceChannel(key);     }          private class ThreadPool {         List idle = new LinkedList();                  ThreadPool(int poolSize) {             for (int i = 0; i < poolSize; i++) {                 WorkerThread thread = new WorkerThread(this);                 thread.setName("Worker" + (i + 1));                 thread.start();                 idle.add(thread);             }         }                  WorkerThread getWorker() {             WorkerThread worker = null;              synchronized (idle) {                 if (idle.size() > 0) {                     worker = (WorkerThread) idle.remove(0);                 }             }             return (worker);         }                  void returnWorker(WorkerThread worker) {             synchronized (idle) {                 idle.add(worker);             }         }     }     private class WorkerThread extends Thread {         private ByteBuffer buffer = ByteBuffer.allocate(1024);         private ThreadPool pool;         private SelectionKey key;         WorkerThread(ThreadPool pool) {             this.pool = pool;         }         public synchronized void run() {             System.out.println(this.getName() + " is ready");             while (true) {                 try {                     this.wait();//等待被notify                 } catch (InterruptedException e) {                     e.printStackTrace();                     this.interrupt();                 }                 if (key == null) {//直到有key                     continue;                 }                 System.out.println(this.getName() + " has been awakened");                 try {                     drainChannel(key);                 } catch (Exception e) { System.out.println("Caught '" + e + "' closing channel");                     try { key.channel().close();                     } catch (IOException ex) {     ex.printStackTrace();                     }                     key.selector().wakeup();                 }                 key = null;                 this.pool.returnWorker(this);             }         }         synchronized void serviceChannel(SelectionKey key) {             this.key = key;             //消除读的关注             key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));             this.notify();         }         void drainChannel(SelectionKey key) throws Exception {             SocketChannel channel = (SocketChannel) key.channel();             int count;             buffer.clear();              while ((count = channel.read(buffer)) > 0) {                 buffer.flip();                 while (buffer.hasRemaining()) {                     channel.write(buffer);                 }                 buffer.clear();             }             if (count < 0) {                 channel.close();                 return;             }             //重新开始关注读事件             key.interestOps(key.interestOps() | SelectionKey.OP_READ);             key.selector().wakeup();         }     }     public static void main(String[] args) throws Exception {         new SelectSocketsThreadPool().go(args);     } }
package cn.chenkangxian.nioconcurrent; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator;  public class SelectSockets {     public static int PORT_NUMBER = 1234;     private ByteBuffer buffer = ByteBuffer.allocate(1024);     public static void main(String[] args) throws Exception {         new SelectSockets().go(args);     }     public void go(String[] args) throws Exception{         int port = PORT_NUMBER; //      if(args.length > 0){ //          port = Integer.parseInt(args[0]); //      } //      System.out.println("Listening on port " + port);         ServerSocketChannel serverChannel = ServerSocketChannel.open();         ServerSocket serverSocket = serverChannel.socket();                  Selector selector = Selector.open();         serverSocket.bind(new InetSocketAddress(port));         serverChannel.configureBlocking(false);         serverChannel.register(selector, SelectionKey.OP_ACCEPT);                  while(true){             int n = selector.select(); //没有轮询,单个selector             if(n == 0){                 continue;              }             Iterator it = selector.selectedKeys().iterator();                          while(it.hasNext()){                 SelectionKey key = (SelectionKey)it.next();                 if(key.isAcceptable()){                     ServerSocketChannel server =                (ServerSocketChannel)key.channel();                     SocketChannel channel = server.accept();        registerChannel(selector,channel,SelectionKey.OP_READ);                     sayHello(channel);                 }                 if(key.isReadable()){                     readDataFromSocket(key);                 }                 it.remove();             }         }     }          protected void registerChannel(Selector selector,             SelectableChannel channel, int ops) throws Exception{         if(channel == null){             return ;          }         channel.configureBlocking(false);         channel.register(selector, ops);     }          protected void readDataFromSocket(SelectionKey key) throws Exception{         SocketChannel socketChannel = (SocketChannel)key.channel();         int count;         buffer.clear(); //Empty buffer         while((count = socketChannel.read(buffer)) > 0){             buffer.flip();              while(buffer.hasRemaining()){                 socketChannel.write(buffer);             }             buffer.clear();          }         if(count < 0){             socketChannel.close();         }     }          private void sayHello(SocketChannel channel) throws Exception{         buffer.clear();         buffer.put("Hello 哈罗! \r\n".getBytes());         buffer.flip();         channel.write(buffer);     } }

到此,关于“Java NIO就绪模式怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯