channel的主要作用:
- close() :可以用来关闭channel
- closeFuture():用来处理channel的关闭
-
- sync :是同步等待channel的关闭
- addListener:是异步等待channel的关闭
- pipeline():添加处理器
- write():将数据写入
- writeAndFlush():将数据写入并刷出
1. 同步和异步处理结果
@Slf4j
public class EventLoopClient {
public static void main(String[] args) throws InterruptedException {
// 带有 Future, Promise 的类型都是异步方法
ChannelFuture channelFuture = new Bootstrap()
// 添加 EventLoop
.group(new NioEventLoopGroup())
// 选择客户端 channel 实现
.channel(NioSocketChannel.class)
// 添加处理器
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel channel) throws Exception {
channel.pipeline().addLast(new StringEncoder());
}
})
// 连接到服务器
// 异步非阻塞, main 发起了调用,真正执行 connect 的是 nio 线程
.connect(new InetSocketAddress("localhost", 8080));
// 使用 sync 方法同步处理结果
// channelFuture.sync();// 阻塞住当前线程,直到 nio 线程连接建立完毕
// Channel channel = channelFuture.channel();
// log.debug("{}",channel);
// // 向服务器发送数据
// channel.writeAndFlush("hello");
// 使用 AddListener(回调对象)方法异步处理结果
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
Channel channel = future.channel();
log.debug("{}",channel);
channel.writeAndFlush("hello");
}
});
}
}
上述代码中,使用了同步和异步处理结果的方式,分析了不同处理方式的发送数据。
2. 同步和异步处理关闭
@Slf4j
public class CloseFutureClient {
public static void main(String[] args) throws InterruptedException {
NioEventLoopGroup group = new NioEventLoopGroup();
ChannelFuture channelFuture = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel channel) throws Exception {
channel.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
channel.pipeline().addLast(new StringEncoder());
}
})
.connect(new InetSocketAddress("localhost", 8080));
Channel channel = channelFuture.sync().channel();
new Thread(() ->{
Scanner scanner = new Scanner(System.in);
while (true) {
String line = scanner.nextLine();
if ("q".equals(line)) {
channel.close();// 异步方法
break;
}
channel.writeAndFlush(line);
}
},"input").start();
// 获取CloseFuture 对象, 1.同步处理关闭 2.异步处理关闭
ChannelFuture closeFuture = channel.closeFuture();
// closeFuture.sync();
// log.debug("处理关闭后的操作");
closeFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
log.debug("处理关闭后的操作");
group.shutdownGracefully();
}
});
}
}
上述代码,对线程关闭同样用同步和异步进行了不同的分析,最后还通过优雅的方式关闭了主线程。
同学们可以写写上述代码,在本地进行验证,更能直观的了解处理线程的不同方式的结果。
本次内容就到这了,后续更精彩!