`

Java NIO原理和使用-观察者模式-聊天工具

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

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

NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后,我们从这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。

Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生,比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙来读取这个channel的内容。

了解了这个基本原理,我们结合代码看看使用,在使用上,也在分两个方向,一个是线程处理,一个是用非线程,后者比较简单,看下面代码:
mport java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;
/**
*
* @author Administrator
* @version
*/
public class NBTest {


  /** Creates new NBTest */
  public NBTest()
  {
  }

  public void startServer() throws Exception
  {
  int channels = 0;
  int nKeys = 0;
  int currentSelector = 0;

  //使用Selector
  Selector selector = Selector.open();

  //建立Channel 并绑定到9000端口
  ServerSocketChannel ssc = ServerSocketChannel.open();
  InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),9000);
  ssc.socket().bind(address);

  //使设定non-blocking的方式。
  ssc.configureBlocking(false);

  //向Selector注册Channel及我们有兴趣的事件
  SelectionKey s = ssc.register(selector, SelectionKey.OP_ACCEPT);
  printKeyInfo(s);

  while(true) //不断的轮询
  {
    debug("NBTest: Starting select");

    //Selector通过select方法通知我们我们感兴趣的事件发生了。
    nKeys = selector.select();
    //如果有我们注册的事情发生了,它的传回值就会大于0
    if(nKeys > 0)
    {
      debug("NBTest: Number of keys after select operation: " +nKeys);

      //Selector传回一组SelectionKeys
      //我们从这些key中的channel()方法中取得我们刚刚注册的channel。
      Set selectedKeys = selector.selectedKeys();
      Iterator i = selectedKeys.iterator();
      while(i.hasNext())
      {
         s = (SelectionKey) i.next();
         printKeyInfo(s);
         debug("NBTest: Nr Keys in selector: " +selector.keys().size());

         //一个key被处理完成后,就都被从就绪关键字(ready keys)列表中除去
         i.remove();
         if(s.isAcceptable())
         {
           // 从channel()中取得我们刚刚注册的channel。
           Socket socket = ((ServerSocketChannel)s.channel()).accept().socket();
           SocketChannel sc = socket.getChannel();

           sc.configureBlocking(false);
           sc.register(selector, SelectionKey.OP_READ |SelectionKey.OP_WRITE);
                      System.out.println(++channels);
         }
         else
         {
           debug("NBTest: Channel not acceptable");
         }
      }
   }
   else
   {
      debug("NBTest: Select finished without any keys.");
   }

  }

}


private static void debug(String s)
{
  System.out.println(s);
}


private static void printKeyInfo(SelectionKey sk)
{
  String s = new String();

  s = "Att: " + (sk.attachment() == null ? "no" : "yes");
  s += ", Read: " + sk.isReadable();
  s += ", Acpt: " + sk.isAcceptable();
  s += ", Cnct: " + sk.isConnectable();
  s += ", Wrt: " + sk.isWritable();
  s += ", Valid: " + sk.isValid();
  s += ", Ops: " + sk.interestOps();
  debug(s);
}


/**
* @param args the command line arguments
*/
public static void main (String args[])
{
  NBTest nbTest = new NBTest();
  try
  {
    nbTest.startServer();
  }
    catch(Exception e)
  {
    e.printStackTrace();
  }
}

}

这是一个守候在端口9000的noblock server例子,如果我们编制一个客户端程序,就可以对它进行互动操作,或者使用telnet 主机名 90000 可以链接上。

通过仔细阅读这个例程,相信你已经大致了解NIO的原理和使用方法,下一篇,我们将使用多线程来处理这些数据,再搭建一个自己的Reactor模式。
分享到:
评论

相关推荐

    JAVA NIO 聊天室程序

    - 这个项目还涉及到了设计模式的使用,比如单例模式用于保证线程安全,观察者模式可能用于实时更新用户界面,以显示新收到的消息。 7. **网络通信协议** - 实现聊天室还需要定义一套通信协议,包括消息格式(例如...

    javaSoket聊天工具

    - 对于大型项目,可能会使用观察者模式(Observer Pattern)来实时更新用户界面,或者工厂模式来创建Socket实例,使代码更易于维护和扩展。 总的来说,Java Socket聊天工具的设计和实现涉及网络编程基础、多线程、...

    [JAVA编程模式与范例].zip

    - JMS(Java Message Service)中,观察者模式用于消息发布/订阅模型。 3. **Java编程范例**: - 多线程编程:通过Thread类或Runnable接口创建线程,理解同步机制如synchronized关键字、wait/notify机制。 - ...

    基于Java的实例源码-聊天程序,包括服务端和客户端.zip

    - **观察者模式**:服务端可能需要监听客户端的连接和断开事件,这时观察者模式可以帮助实现消息通知。 7. **异常处理**: - 在网络编程中,错误处理非常重要,例如网络中断、超时等异常,都需要进行捕获和处理。...

    java聊天工具

    - 良好的软件设计通常会使用设计模式,如单例模式用于网络连接管理,工厂模式用于创建UI组件,观察者模式用于实时更新聊天界面等。 综上所述,"java聊天工具"是一个涵盖了Java GUI编程、网络通信、多线程、数据...

    java-ICQ

    例如,工厂模式可能用于创建不同类型的连接,观察者模式用于实时更新用户界面,单例模式用于管理全局资源等。 通过对Java-ICQ源码的深入学习,开发者不仅可以掌握即时通讯系统的设计原理,还能提升在Java网络编程、...

    JAVA 开发Java聊天室程序(java)130226

    6. **设计模式**:为了使代码结构清晰,易于维护,开发者可能会采用设计模式,如工厂模式(创建线程或Socket实例)、单例模式(用于服务器对象)或观察者模式(用于广播消息到所有在线用户)。 7. **异常处理**:在...

    JavaSwing的QQ聊天系统

    6. **设计模式**:在聊天系统中,可能会用到单例模式来保证服务器连接的唯一性,工厂模式用于创建UI组件,观察者模式(Observer)用于实时更新聊天窗口的消息显示。 7. **数据结构**:聊天记录通常会存储在队列或...

    内网版本聊天室-JAVA

    10. **设计模式**:良好的软件设计往往遵循一些设计模式,如单例模式用于保证聊天室服务的唯一性,工厂模式用于对象的创建,观察者模式用于实时更新用户界面等。 以上是内网版本聊天室-JAVA项目中可能涉及的主要...

    北京圣思园科技有限公司JAVA面授培训大纲

    - **设计模式**:介绍工厂方法、观察者、策略、装饰、模板方法、命令等模式的原理与应用案例。 - **Java NIO**:学习Java NIO的新特性及其在高性能I/O处理中的应用。 - **并发包详解**:深入分析ConcurrentHashMap、...

    java多线程聊天室

    9. **设计模式**:在开发过程中,可能会应用到如工厂模式(创建线程)、观察者模式(发布新消息时通知所有用户)等设计模式,提高代码的可读性和可维护性。 10. **课程设计报告**:在项目完成后,通常需要编写一份...

    基于java的防QQ即时通信系统源码

    - 在开发过程中,设计模式如单例、工厂、观察者等可以提高代码的可读性和可维护性。 9. **TCP/IP协议** - TCP协议用于保证消息的可靠传输,防止数据丢失或重复。 10. **消息协议设计** - 自定义的消息协议,如...

    java聊天室

    Java聊天室是一个基于Java编程语言实现的实时通讯应用,...总的来说,Java聊天室的开发涉及了Java网络编程、多线程、设计模式、数据序列化、安全性和用户界面等多个方面,是学习和展示Java综合能力的一个良好实践项目。

    Java聊天室毕业设计完整版+数据库

    8. **设计模式**:良好的软件设计通常会采用设计模式,如工厂模式用于创建对象,观察者模式用于实现消息发布与订阅,单例模式用于数据库连接池等。 9. **测试与调试**:在开发过程中,单元测试、集成测试以及性能...

    基于Socket的Java聊天室程序

    9. **设计模式**:在实现聊天室时,可能涉及到单例模式(ServerSocket的创建)、观察者模式(用于广播消息到所有客户端)等设计模式,它们可以帮助提高代码的可读性和可维护性。 通过学习和实践这个Java聊天室程序...

    java版飞鸽传书源码

    9. **设计模式**:为了实现良好的代码结构和可维护性,源码中可能运用了多种设计模式,如工厂模式、单例模式、观察者模式等。 10. **测试**:为了确保代码质量,源码可能包含了单元测试和集成测试,使用JUnit或其他...

    Java经典项目集锦

    12. **设计模式**:经典项目中常常会涉及单例模式、工厂模式、观察者模式等常见设计模式,这有助于提高代码的可维护性和复用性。 13. **Java Web开发**:包括Servlet、JSP、Filter、Listener等,学习者可以通过构建...

    即时通信系统(Java实现)Java源码

    8. **设计模式**:在大型项目中,设计模式如单例、工厂、观察者等被广泛使用,以提高代码的可维护性和扩展性。在即时通信系统中,例如,服务器可能使用单例模式以确保只有一个实例存在,而消息发布可能采用观察者...

    java版在线聊天系统

    观察者模式实现事件驱动,当消息到达时通知相关用户。 在实际开发中,还需要考虑到负载均衡、集群部署、故障恢复等运维问题,这可能涉及到Nginx、Docker、Kubernetes等技术。 总的来说,Java版在线聊天系统是一个...

    Java聊天室程序(java).zip

    11. **设计模式**: 聊天室程序可能运用到一些设计模式,如工厂模式(创建连接对象)、观察者模式(更新用户界面)或单例模式(确保服务器对象只存在一个实例)。 12. **测试与调试**: 为了确保程序的稳定性和可靠性...

Global site tag (gtag.js) - Google Analytics