一、应用场景
使用场景:
- 用户自定义任务:业务逻辑复杂耗时,(可能会将pip堵塞),放入异步队列taskQueue中
- 用户自定义定时任务:可自定义任务调度时间,放入异步队列taskQueue中
- 其它线程调度任务:可不在当前线程进行调度执行业务逻辑,即:其它线程可以调用当前线程的channel进行业务处理
二、用户自定义任务案例
调用的是execut方法,run方法主体为业务逻辑,设置后可异步执行
此任务会放入NioEventLoop的taskQueue中
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().eventLoop().execute(new Runnable() {
@Override
public void run() {
ctx.channel().writeAndFlush(Unpooled.copiedBuffer("hello 客户端",CharsetUtil.UTF_8));
}
});
}
三:用户自定义定时任务
调用的是schedule方法,run方法体为业务逻辑,可设置定时时长,和时间单位
此任务会放入NioEventLoop的scheduledTaskQueue中
例如:5秒后给客户端发送:hello 客户端
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().eventLoop().schedule(new Runnable() {
@Override
public void run() {
ctx.channel().writeAndFlush(Unpooled.copiedBuffer("hello 客户端",CharsetUtil.UTF_8));
}
},5, TimeUnit.SECONDS);
}
四:非当前线程调度
初始化时维护一个ConcurrentHashMap,初始化管道的时候将当前管道的hashcode和socketChannel进行维护
此任务会放入NioEventLoop的taskQueue中,当然也可以使用定时任务,则会放入到scheduledTaskQueue中
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(io.netty.channel.socket.SocketChannel socketChannel) throws Exception {
map.put(socketChannel.hashCode(),socketChannel);
socketChannel.pipeline().addLast(new ServerHandler(map));
}
});
Handler中:新增一个map和构造器,遍历map对map中所有的连接进行推送消息
private Map<Integer, SocketChannel> map;
//每次与客户端建立连接构建handler时都会传入一个map,其中有当前客户端连接和之前的客户端的连接
public ServerHandler(Map<Integer, SocketChannel> map){
this.map = map;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
map.forEach((key,value)->{
value.writeAndFlush(Unpooled.copiedBuffer("向"+key+"发送消息", CharsetUtil.UTF_8));
});
}
五:总结
- 普通异步任务使用execute方法,会放入到taskQueue中
- 定时异步任务使用schedule方法,会放入到scheduledTaskQueue中
- 队列中任务消费顺序是按照放入队列的顺序,依次进行消费