标签:bst sele 实现 逻辑 控制 pen elf ati and
public interface EventExecutorGroup extends ScheduledExecutorService, Iterable<EventExecutor> {
//省略其他方法
EventExecutor next();
@Override
Iterator<EventExecutor> iterator();
}
public interface EventExecutor extends EventExecutorGroup {
//省略其他方法
@Override
EventExecutor next();
EventExecutorGroup parent();
boolean inEventLoop();
boolean inEventLoop(Thread thread);
我们在使用JDK线程池时,任务之间其实是独立的,我们并不关心他们的执行先后顺序,因为我们的任务都是原子的,因此我们并不关心任务被哪个线程拿到执行。所以,JDK的线程之并没有给我们提供获取内部线程的方法,我们也不需要。
首先,我们从Netty的线程模型入手,分析这里的设计原因:在Netty中,我们的一个Channel是绑定到一个线程上的,也就是一个Channel绑定到一个线程上,一个线程可以绑定多个Channel。绑定的好处是一个Channel上的所有操作都是串行的,因为只有一个线程处理这个Channel。如果是直接把Channel的操作提交给线程池,那么可能读写等操作乱序,需要额外的机制保证并发,这种绑定避免了这些额外开销。
对比JDK和Netty的线程池实现,总结如下:JDK线程池提交的任务是独立的,Netty提交的任务是需要保证执行顺序的。
从第三点我们知道,Netty中,我们需要把Channel绑定到一个特定的线程上去,因此我们需要获取到线程池的某个线程,并且这个线程可以当成一个线程池来使用,我们可以向这个线程提交任务。EventExecutor也提供了inEventLoop方法用户判断当前代码执行是不是在绑定的线程,如果不是,我们就需要通过提交任务的方式提交,如果是,我们就可以直接执行,因此我们可以看到很多类似代码
//获取绑定的线程
EventLoop eventLoop = eventLoop();
//如果当前线程是绑定的线程,直接执行
if (eventLoop.inEventLoop()) {
setReadPending0(readPending);
//否则,提交到绑定线程中执行
} else {
eventLoop.execute(new Runnable() {
@Override
public void run() {
setReadPending0(readPending);
}
});
}
@Override
public Future<?> submit(Runnable task) {
return next().submit(task);
}
@Override
protected void run() {
for (;;) {
Runnable task = takeTask();
if (task != null) {
task.run();
updateLastExecutionTime();
}
if (confirmShutdown()) {
break;
}
}
}
public static void main(String[] args) {
EventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(5);
eventExecutorGroup.execute(() -> System.out.println(Thread.currentThread().getName()));
eventExecutorGroup.execute(() -> System.out.println(Thread.currentThread().getName()));
eventExecutorGroup.execute(() -> System.out.println(Thread.currentThread().getName()));
eventExecutorGroup.execute(() -> System.out.println(Thread.currentThread().getName()));
EventExecutor eventExecutor = eventExecutorGroup.next();
eventExecutor.execute(() -> System.out.println(Thread.currentThread().getName()));
eventExecutor.execute(() -> System.out.println(Thread.currentThread().getName()));
eventExecutor.execute(() -> System.out.println(Thread.currentThread().getName()));
eventExecutor.execute(() -> System.out.println(Thread.currentThread().getName()));
}
defaultEventExecutorGroup-2-1
defaultEventExecutorGroup-2-2
defaultEventExecutorGroup-2-3
defaultEventExecutorGroup-2-4
defaultEventExecutorGroup-2-5
defaultEventExecutorGroup-2-5
defaultEventExecutorGroup-2-5
defaultEventExecutorGroup-2-5
public interface EventLoopGroup extends EventExecutorGroup {
@Override
EventLoop next();
ChannelFuture register(Channel channel);
ChannelFuture register(ChannelPromise promise);
@Deprecated
ChannelFuture register(Channel channel, ChannelPromise promise);
}
EventLoopGroup bossGroup = new NioEventLoopGroup();
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
new ServerBootstrap().group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new FixedLengthFrameDecoder(3))
.localAddress(8888)
.bind()
.sync()
.channel()
.closeFuture()
.sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
workerGroup上,这两个线程池对Selector的io操作进行处理
标签:bst sele 实现 逻辑 控制 pen elf ati and
原文地址:https://www.cnblogs.com/zby9527/p/13206654.html