accept 阻塞_Java 非阻塞 IO 和异步 IO,看了都说好

点击上方 "程序员小乐"关注, 星标或置顶一起成长

第一时间与你相约

每日英文

We all have a past. It’s how you deal with it.

每个人都有过去,只是取决于你怎么去处理。

每日掏心话

人不都是这样吗,安慰别人的时候头头是道,自己遇上点过不去的坎立马无法自拔,道理都懂,只是情绪作祟,故事太撩人。

来自:JavaDoop | 责编:乐乐

链接:javadoop.com/post/nio-and-aio

abfaefd0357646acaa8112ba788f67ca

程序员小乐(ID:study_tech)第 705 次推文 图片来自网络

往日回顾:千万别惹程序员,否则会在代码注释里,告诉这家公司有多坑!、ef+Npoi导出百万行excel之踩坑记

正文

上一篇文章介绍了 Java NIO 中 Buffer、Channel 和 Selector 的基本操作,主要是一些接口操作,比较简单。

本文将介绍非阻塞 IO 和异步 IO,也就是大家耳熟能详的 NIO 和 AIO。很多初学者可能分不清楚异步和非阻塞的区别,只是在各种场合能听到异步非阻塞这个词。

本文会先介绍并演示阻塞模式,然后引入非阻塞模式来对阻塞模式进行优化,最后再介绍 JDK7 引入的异步 IO,由于网上关于异步 IO 的介绍相对较少,所以这部分内容我会介绍得具体一些。

希望看完本文,读者可以对非阻塞 IO 和异步 IO 的迷雾看得更清晰些,或者为初学者解开一丝丝疑惑也是好的。

NIO,JDK1.4,New IO,Non-Blocking IO

NIO.2,JDK7,More New IO,Asynchronous IO,严格地说 NIO.2 不仅仅引入了 AIO

阻塞模式 IO

我们已经介绍过使用 Java NIO 包组成一个简单的客户端-服务端网络通讯所需要的 ServerSocketChannel、SocketChannel 和 Buffer,我们这里整合一下它们,给出一个完整的可运行的例子:

public class Server {

public static void main(String[] args) throws IOException {

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

// 监听 8080 端口进来的 TCP 链接

serverSocketChannel.socket().bind(new InetSocketAddress(8080));

while (true) {

// 这里会阻塞,直到有一个请求的连接进来

SocketChannel socketChannel = serverSocketChannel.accept();

// 开启一个新的线程来处理这个请求,然后在 while 循环中继续监听 8080 端口

SocketHandler handler = new SocketHandler(socketChannel);

new Thread(handler).start();

}

}

}

这里看一下新的线程需要做什么,SocketHandler:

public class SocketHandler implements Runnable {

private SocketChannel socketChannel;

public SocketHandler(SocketChannel socketChannel) {

this.socketChannel = socketChannel;

}

@Override

public void run() {

ByteBuffer buffer = ByteBuffer.allocate(1024);

try {

// 将请求数据读入 Buffer 中

int num;

while ((num = socketChannel.read(buffer)) > 0) {

// 读取 Buffer 内容之前先 flip 一下

buffer.flip();

// 提取 Buffer 中的数据

byte[] bytes = new byte[num];

buffer.get(bytes);

String re = new String(bytes, "UTF-8");

System.out.println("收到请求:" + re);

// 回应客户端

ByteBuffer writeBuffer = ByteBuffer.wrap(("我已经收到你的请求,你的请求内容是:" + re).getBytes());

socketChannel.write(writeBuffer);

buffer.flip();

}

} catch (IOException e) {

IOUtils.closeQuietly(socketChannel);

}

}

}

最后,贴一下客户端 SocketChannel 的使用,客户端比较简单:

public class SocketChannelTest {

public static void main(String[] args) throws IOException {

SocketChannel socketChannel = SocketChannel.open();

socketChannel.connect(new InetSocketAddress("localhost

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值