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模式。
分享到:
相关推荐
- 这个项目还涉及到了设计模式的使用,比如单例模式用于保证线程安全,观察者模式可能用于实时更新用户界面,以显示新收到的消息。 7. **网络通信协议** - 实现聊天室还需要定义一套通信协议,包括消息格式(例如...
- 对于大型项目,可能会使用观察者模式(Observer Pattern)来实时更新用户界面,或者工厂模式来创建Socket实例,使代码更易于维护和扩展。 总的来说,Java Socket聊天工具的设计和实现涉及网络编程基础、多线程、...
- JMS(Java Message Service)中,观察者模式用于消息发布/订阅模型。 3. **Java编程范例**: - 多线程编程:通过Thread类或Runnable接口创建线程,理解同步机制如synchronized关键字、wait/notify机制。 - ...
- **观察者模式**:服务端可能需要监听客户端的连接和断开事件,这时观察者模式可以帮助实现消息通知。 7. **异常处理**: - 在网络编程中,错误处理非常重要,例如网络中断、超时等异常,都需要进行捕获和处理。...
- 良好的软件设计通常会使用设计模式,如单例模式用于网络连接管理,工厂模式用于创建UI组件,观察者模式用于实时更新聊天界面等。 综上所述,"java聊天工具"是一个涵盖了Java GUI编程、网络通信、多线程、数据...
例如,工厂模式可能用于创建不同类型的连接,观察者模式用于实时更新用户界面,单例模式用于管理全局资源等。 通过对Java-ICQ源码的深入学习,开发者不仅可以掌握即时通讯系统的设计原理,还能提升在Java网络编程、...
6. **设计模式**:为了使代码结构清晰,易于维护,开发者可能会采用设计模式,如工厂模式(创建线程或Socket实例)、单例模式(用于服务器对象)或观察者模式(用于广播消息到所有在线用户)。 7. **异常处理**:在...
6. **设计模式**:在聊天系统中,可能会用到单例模式来保证服务器连接的唯一性,工厂模式用于创建UI组件,观察者模式(Observer)用于实时更新聊天窗口的消息显示。 7. **数据结构**:聊天记录通常会存储在队列或...
10. **设计模式**:良好的软件设计往往遵循一些设计模式,如单例模式用于保证聊天室服务的唯一性,工厂模式用于对象的创建,观察者模式用于实时更新用户界面等。 以上是内网版本聊天室-JAVA项目中可能涉及的主要...
- **设计模式**:介绍工厂方法、观察者、策略、装饰、模板方法、命令等模式的原理与应用案例。 - **Java NIO**:学习Java NIO的新特性及其在高性能I/O处理中的应用。 - **并发包详解**:深入分析ConcurrentHashMap、...
9. **设计模式**:在开发过程中,可能会应用到如工厂模式(创建线程)、观察者模式(发布新消息时通知所有用户)等设计模式,提高代码的可读性和可维护性。 10. **课程设计报告**:在项目完成后,通常需要编写一份...
- 在开发过程中,设计模式如单例、工厂、观察者等可以提高代码的可读性和可维护性。 9. **TCP/IP协议** - TCP协议用于保证消息的可靠传输,防止数据丢失或重复。 10. **消息协议设计** - 自定义的消息协议,如...
Java聊天室是一个基于Java编程语言实现的实时通讯应用,...总的来说,Java聊天室的开发涉及了Java网络编程、多线程、设计模式、数据序列化、安全性和用户界面等多个方面,是学习和展示Java综合能力的一个良好实践项目。
8. **设计模式**:良好的软件设计通常会采用设计模式,如工厂模式用于创建对象,观察者模式用于实现消息发布与订阅,单例模式用于数据库连接池等。 9. **测试与调试**:在开发过程中,单元测试、集成测试以及性能...
9. **设计模式**:在实现聊天室时,可能涉及到单例模式(ServerSocket的创建)、观察者模式(用于广播消息到所有客户端)等设计模式,它们可以帮助提高代码的可读性和可维护性。 通过学习和实践这个Java聊天室程序...
9. **设计模式**:为了实现良好的代码结构和可维护性,源码中可能运用了多种设计模式,如工厂模式、单例模式、观察者模式等。 10. **测试**:为了确保代码质量,源码可能包含了单元测试和集成测试,使用JUnit或其他...
12. **设计模式**:经典项目中常常会涉及单例模式、工厂模式、观察者模式等常见设计模式,这有助于提高代码的可维护性和复用性。 13. **Java Web开发**:包括Servlet、JSP、Filter、Listener等,学习者可以通过构建...
8. **设计模式**:在大型项目中,设计模式如单例、工厂、观察者等被广泛使用,以提高代码的可维护性和扩展性。在即时通信系统中,例如,服务器可能使用单例模式以确保只有一个实例存在,而消息发布可能采用观察者...
观察者模式实现事件驱动,当消息到达时通知相关用户。 在实际开发中,还需要考虑到负载均衡、集群部署、故障恢复等运维问题,这可能涉及到Nginx、Docker、Kubernetes等技术。 总的来说,Java版在线聊天系统是一个...
11. **设计模式**: 聊天室程序可能运用到一些设计模式,如工厂模式(创建连接对象)、观察者模式(更新用户界面)或单例模式(确保服务器对象只存在一个实例)。 12. **测试与调试**: 为了确保程序的稳定性和可靠性...