[Java]对NIO中非阻塞式编程的个人浅见
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了[Java]对NIO中非阻塞式编程的个人浅见,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4106字,纯文字阅读大概需要6分钟。
内容图文
![[Java]对NIO中非阻塞式编程的个人浅见](/upload/InfoBanner/zyjiaocheng/601/7c0e31bcbdc743ff844690ebe05e7245.jpg)
个人总结:
阻塞式编程:客户端向服务器端建立通道,发送数据时,由于服务器端不知道数据什么时候发送完毕或者无法验证数据的真假时,造成阻塞,可用多线程方式降低阻塞。
非阻塞式编程:当客户端向服务器端建立通道时,需要在选择器上进行通道的注册,选择器的功能是监听已注册的通道的某种任务的状态(包含多种状态:读、写、连接、接受数据),当其中一种状态完全准备就绪时,选择器才会将这个任务分配到一个或多个服务器的线程上,进行操作运行
基于TCP:
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import org.junit.Test;
public class TestNonBlockingNIO {
//客户端
@Test
public void client() throws IOException {
//1.打开通道
SocketChannel sChannel=SocketChannel.open(new InetSocketAddress("127.0.0.1",9898));
//2.切换为非阻塞模式
sChannel.configureBlocking(false);
//3.分配指定大小的缓冲区
ByteBuffer buf=ByteBuffer.allocate(1024);
//4.发送给服务器端
Scanner scan=new Scanner(System.in);
while(scan.hasNext()) {
String str=scan.next();
buf.put((new Date().toString()+"\n"+str).getBytes());
buf.flip();
sChannel.write(buf);
buf.clear();
}
//5.关闭通道
sChannel.close();
}
//服务器端
@Test
public void server() throws IOException {
//1.获取通道
ServerSocketChannel ssChannel=ServerSocketChannel.open();
//2.切换为非阻塞模式
ssChannel.configureBlocking(false);
//3.绑定连接
ssChannel.bind(new InetSocketAddress(9898));
//4.获取选择器
Selector selector=Selector.open();
//5.将通道注册到选择器上,并且指定“监听接受状态(事件)”
//什么时候接受状态准备就绪了,再去获取连接
ssChannel.register(selector, SelectionKey.OP_ACCEPT);
//6.轮询式的获取选择器上已经“准备就绪”的事件
while(selector.select()>0) {//当selector.select()>0表示已有事件就绪
//7.获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
Iterator<SelectionKey> it=selector.selectedKeys().iterator();//selectedKeys()集合中包含了所有监听的事件
while(it.hasNext()) {
//8.获取准备“就绪”的事件
SelectionKey sk=it.next();
//9.判断具体是什么事件准备就绪
if(sk.isAcceptable()) {
//10.若“接受就绪”,获取客户端连接
SocketChannel sChannel=ssChannel.accept();
//11.切换非阻塞模式
sChannel.configureBlocking(false);
//12.将该通道注册到选择器中
sChannel.register(selector, SelectionKey.OP_READ);
}else if(sk.isReadable()) {
//13.获取当前选择器上“读就绪”状态的通道
SocketChannel sChannel=(SocketChannel) sk.channel();
//14.读取数据
ByteBuffer buf=ByteBuffer.allocate(1024);
int len=0;
while((len=sChannel.read(buf))>0) {
buf.flip();
System.out.println(new String(buf.array(),0,len));
buf.clear();
}
}
//15.取消选择键SelextionKey,以保证下一次监听时,它不在就绪状态
it.remove();
}
}
}
}
先运行服务器端,再运行客户端:
基于UDP:
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import org.junit.Test;
public class TestNonBlockingNIO2 {
//发送端
@Test
public void send() throws IOException {
DatagramChannel dc=DatagramChannel.open();
dc.configureBlocking(false);
ByteBuffer buf=ByteBuffer.allocate(1024);
Scanner scan=new Scanner(System.in);
while(scan.hasNext()) {
String str=scan.next();
buf.put((new Date().toString()+":\n"+str).getBytes());
buf.flip();
dc.send(buf, new InetSocketAddress("127.0.0.1",9898));
buf.clear();
}
dc.close();
}
//接受端
@Test
public void receive() throws IOException {
DatagramChannel dc=DatagramChannel.open();
dc.configureBlocking(false);
dc.bind(new InetSocketAddress(9898));
Selector selector=Selector.open();
dc.register(selector, SelectionKey.OP_READ);
while(selector.select()>0) {
Iterator<SelectionKey> it=selector.selectedKeys().iterator();
while(it.hasNext()) {
SelectionKey sk=it.next();
if(sk.isReadable()) {
ByteBuffer buf=ByteBuffer.allocate(1024);
dc.receive(buf);
buf.flip();
System.out.println(new String(buf.array(),0,buf.limit()));
buf.clear();
}
it.remove();
}
}
}
}
先运行接受端,后运行发送端:
内容总结
以上是互联网集市为您收集整理的[Java]对NIO中非阻塞式编程的个人浅见全部内容,希望文章能够帮你解决[Java]对NIO中非阻塞式编程的个人浅见所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。