多种IO设计模式

[size=medium]Java通信的几种IO设计
[size=large][b]阻塞IO[/b][/size]

同步阻塞最常用的一种用法,使用也是最简单的,但是 I/O 性能一般很差,CPU 大部分在空闲状态。下面是一个简单的基于TCP的同步阻塞的Socket服务端例子:
@Test
public void testBlockIoSocket() throws Exception
{
ServerSocket serverSocket = new ServerSocket(10002);
Socket socket = null;
try
{
while (true)
{
socket = serverSocket.accept();
System.out.println("socket连接:" + socket.getRemoteSocketAddress().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true)
{
String readLine = in.readLine();
System.out.println("收到消息" + readLine);
if("end".equals(readLine))
{
break;
}
//客户端断开连接
socket.sendUrgentData(0xFF);
}
}
}
catch (SocketException se)
{
System.out.println("客户端断开连接");
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
System.out.println("socket关闭:" + socket.getRemoteSocketAddress().toString());
socket.close();
}
}
设计分析:
由于服务器端是单线程的,在第一个连接的客户端阻塞了线程后,第二个客户端必须等待第一个断开后才能连接。
所有的客户端连接在请求服务端时都会阻塞住,等待前面的完成。即使是使用短连接,数据在写入 OutputStream 或者从 InputStream 读取时都有可能会阻塞。这在大规模的访问量或者系统对性能有要求的时候是不能接受的。


[size=large][b]阻塞IO + 每个请求创建线程/线程池[/b][/size]

通常解决这个问题的方法是使用多线程技术,一个客户端一个处理线程,出现阻塞时只是一个线程阻塞而不会影响其它线程工作;为了减少系统线程的开销,采用线程池的办法来减少线程创建和回收的成本。模式如下图:
[img]data:image/png;base64,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[/img]

每当来一个客户端的连接的时候,我们服务器就new 一个线程来处理它。在服务器的主程序是不阻塞的,阻塞的只是这个线程。这样也是我目前最常用的模式。

在单个线程处理中,我人为的使单个线程read后阻塞5秒,就像前面说的,出现阻塞也只是在单个线程中,没有影响到另一个客户端的处理。
  这种阻塞IO的解决方案在大部分情况下是适用的,在出现NIO之前是最通常的解决方案,Tomcat里阻塞IO的实现就是这种方式。但是如果是大量的长连接请求呢?不可能创建几百万个线程保持连接。再退一步,就算线程数不是问题,如果这些线程都需要访问服务端的某些竞争资源,势必需要进行同步操作,这本身就是得不偿失的。


[size=large][b]非阻塞IO + IO multiplexing[/b][/size]  Java从1.4开始提供了NIO工具包,这是一种不同于传统流IO的新的IO方式,使得Java开始对非阻塞IO支持;NIO并不等同于非阻塞IO,只要设置Blocking属性就可以控制阻塞非阻塞。至于NIO的工作方式特点原理这里一概不说,以后会写。模式如下图:

[img]data:image/png;base64,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[/img]

public class NioNonBlockingSelectorTest
{
Selector selector;
private ByteBuffer receivebuffer = ByteBuffer.allocate(1024);

@Test
public void testNioNonBlockingSelector()
throws Exception
{
selector = Selector.open();
SocketAddress address = new InetSocketAddress(10002);
ServerSocketChannel channel = ServerSocketChannel.open();
channel.socket().bind(address);
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_ACCEPT);

while(true)
{
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
handleKey(selectionKey);
}
}
}

private void handleKey(SelectionKey selectionKey) throws IOException
{
ServerSocketChannel server = null;
SocketChannel client = null;
if(selectionKey.isAcceptable())
{
server = (ServerSocketChannel)selectionKey.channel();
client = server.accept();
System.out.println("客户端: " + client.socket().getRemoteSocketAddress().toString());
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
if(selectionKey.isReadable())
{
client = (SocketChannel)selectionKey.channel();
receivebuffer.clear();
int count = client.read(receivebuffer);
if (count > 0) {
String receiveText = new String( receivebuffer.array(),0,count);
System.out.println("服务器端接受客户端数据--:" + receiveText);
client.register(selector, SelectionKey.OP_READ);
}
}
}

}

Java NIO提供的非阻塞IO并不是单纯的非阻塞IO模式,而是建立在Reactor模式上的IO复用模型;在IO multiplexing Model中,对于每一个socket,一般都设置成为non-blocking,但是整个用户进程其实是一直被阻塞的。只不过进程是被select这个函数阻塞,而不是被socket IO给阻塞,所以还是属于非阻塞的IO。

网络IO优化

  对于网络IO有一些基本的处理规则如下:

  1。减少交互的次数。比如增加缓存,合并请求。

  2。减少传输数据大小。比如压缩后传输、约定合理的数据协议。

  3。减少编码。比如提前将字符转化为字节再传输。

  4。根据应用场景选择合适的交互方式,同步阻塞,同步非阻塞,异步阻塞,异步非阻塞。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值