一、netty
1.服务端代码
(1)服务端:
package com.netty.test.socekt;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class NettyServer {
public static void main(String[] args) {
ServerBootstrap bootstrap = new ServerBootstrap();
EventLoopGroup boos = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
try {
bootstrap.group(boos, worker)
.channel(NioServerSocketChannel.class) //channel类型
.option(ChannelOption.SO_BACKLOG, 128) //线程队列连接个数
// .handler(null) //忘 boos里加
.childHandler(new ChannelInitializer<SocketChannel>() { //服务端的回调函数 往worker里加
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyServerHandler());
}
});
//启动服务 采用异步方式 并绑定端口
ChannelFuture sync = bootstrap.bind("127.0.0.1", 6667).sync();
sync.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()){
System.out.println("socket server is running listener 6666");
}else {
System.out.println("socket server is not running listener 6666");
}
}
});
System.out.println("服务端启动 !!!");
//对关闭频道进行监听
ChannelFuture channelFuture = sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boos.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
(2)处理器:
package com.netty.test.socekt;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import java.util.concurrent.TimeUnit;
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("ctx==== " + ctx);
ByteBuf buf = (ByteBuf)msg;
System.out.println(buf.toString(CharsetUtil.UTF_8));
/** 任务执行器 队列任务*/
ctx.channel().eventLoop().execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10 * 1000);
ctx.writeAndFlush(Unpooled.copiedBuffer("客户端=====1",CharsetUtil.UTF_8));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
ctx.channel().eventLoop().execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10 * 1000); //在一个线程中 过 第一次的10秒加上现在的10秒 一共 20秒
ctx.writeAndFlush(Unpooled.copiedBuffer("客户端=====2",CharsetUtil.UTF_8));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
/** 用户自定义定时任务 */
ctx.channel().eventLoop().schedule(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10 * 1000); //在一个线程中 过 第一次的10秒加上现在的10秒 一共 20秒
ctx.writeAndFlush(Unpooled.copiedBuffer("客户端=====3",CharsetUtil.UTF_8));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},2, TimeUnit.SECONDS);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("数据读取完毕!",CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
2.客户端代码:
(1) 服务器:
package com.netty.test.socekt;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class NettyClient {
public static void main(String[] args) {
EventLoopGroup eventExecutors = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.group(eventExecutors)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
System.out.println("客户端启动!!!!!");
ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6667).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
eventExecutors.shutdownGracefully();
}
}
}
(2)处理器:
package com.netty.test.socekt;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
/**
* 当通道就绪触发
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client ctx === " + ctx);
ctx.writeAndFlush(Unpooled.copiedBuffer("我是 " + Thread.currentThread().getName() + " 来了", CharsetUtil.UTF_8));
}
/**
* 当通道有读取事件触发
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
System.out.println("客户端收到消息 " + buf.toString(CharsetUtil.UTF_8));
}
}
3.服务端代码分段debug分析
架构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifyXF3Df-1615391452194)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210309165553220.png)]
//第一步:初始化服务端引导器 这就是一个空的引导器未进行任何初始化工作 因为父类构造函数内部无任何实现
ServerBootstrap bootstrap = new ServerBootstrap();
//==================调用以下方法==================
EventLoopGroup boos = new NioEventLoopGroup();
//该类的相关结构如下所示
1. NioEventLoopGroup extends MultithreadEventLoopGroup
2. MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup
3. MultithreadEventExecutorGroup extends AbstractEventExecutorGroup
4. AbstractEventExecutorGroup implements EventExecutorGroup
5. EventExecutorGroup extends ScheduledExecutorService, Iterable<EventExecutor>
6. ScheduledExecutorService extends ExecutorService
7. ExecutorService extends Executor
1.先看一下接口Executer为java包下(为该框架任务调度、定时任务做准备)
1.先看一下接口Executer为java包下(为该框架任务调度、定时任务做准备)
接口解释:该接口执行已提交的 Runnable 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、 调度等)分离开来的方法。通常使用 Executor 而不是显式地创建线程。例如,可能会使用以下方法,而不是为一组任务中的每个 任务调用new Thread(new(RunnableTask())).start():
方法:void execute(Runnable command);
解释:在将来的某个时间执行给定的命令。 该命令可以在一个新的线程中执行,在一个线程池,或者调用线程,在酌情Executor执行
2.ExecutorService 为java包下(为该框架任务调度、定时任务做准备)
2.ExecutorService 为java包下(为该框架任务调度、定时任务做准备)
接口解释:Executor 提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。
可以关闭 ExecutorService,这将导致其拒绝新任务。提供两个方法来关闭 ExecutorService.shutdown() 方法在终止前 允许执行以前提交的任务,而 shutdownNow() 方法阻止等待任务启动并试图停止当前正在执行的任务。在终止时,执行程序没有 任务在执行,也没有任务在等待执行,并且无法提交新任务。应该关闭未使用的 ExecutorService 以允许回收其资源。
通过创建并返回一个可用于取消执行和/或等待完成的 Future,方法 submit 扩展了基本方法Executor.execute(java.
lang.Runnable)。方法 invokeAny 和 invokeAll 是批量执行的最常用形式,它们执行任务 collection,然后等待至少一 个,或全部任务完成(可使用 ExecutorCompletionService 类来编写这些方法的自定义变体)。
Executors 类提供了用于此包中所提供的执行程序服务的工厂方法。
方法: void shutdown();
方法解释:启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
方法: boolean isShutdown();
方法解释:如果此执行程序已关闭,则返回 true。
方法: boolean isTerminated();
方法解释:如果关闭后所有任务都已完成,则返回 true。
方法: boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
方法解释:请求关闭、发生超时或者当前线程中断,无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行。
参数解释: timeout -- 最长等待时间
unit -- 参数的时间单位
方法: <T> Future<T> submit(Callable<T> task);
方法解释:提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
参数解释: task -- 要提交的任务
返回解释: Future -- 表示任务等待完成的 Future
方法: Future<?> submit(Runnable task);
方法解释:提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
参数解释: task -- 要提交的任务
返回解释: Future -- 表示任务等待完成的 Future
方法: <T> Future<T> submit(Runnable task, T result);
方法解释:提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
参数解释: task -- 要提交的任务
result -- 返回的结果
返回解释: Future -- 表示任务等待完成的 Future
方法: <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
方法解释:执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。
参数解释: tasks -- 任务 collection (就是执行任务的集合)
返回解释: List<Future<T>> -- 表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。如果操作未超 时,则已完成所有任务。如果确实超时了,则某些任务尚未完成
方法: <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit) throws InterruptedException;
方法解释:执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。
参数解释: tasks -- 任务 collection (就是执行任务的集合)
timeout -- 最长等待时间
unit -- 参数的时间单位
返回解释: List<Future<T>> -- 表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。如果操作未超 时,则已完成所有任务。如果确实超时了,则某些任务尚未完成
方法: <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
方法解释:执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。
参数解释: tasks -- 任务 collection (就是执行任务的集合)
返回解释: T -- 某个任务返回的结果
方法: <T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
方法解释: 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。
参数解释: tasks -- 任务 collection (就是执行任务的集合)
timeout -- 最长等待时间
unit -- 参数的时间单位
返回解释: T -- 某个任务返回的结果
3.ScheduledExecutorService 为Java包下(为该框架定时任务做准备)
3.ScheduledExecutorService 为Java包下(为该框架定时任务做准备)
接口解释:一个 ExecutorService,可安排在给定的延迟后运行或定期执行的命令。
schedule 方法使用各种延迟创建任务,并返回一个可用于取消或检查执行的任务对象。scheduleAtFixedRate 和 scheduleWithFixedDelay 方法创建并执行某些在取消前一直定期运行的任务。
用 Executor.execute(java.lang.Runnable) 和 ExecutorService 的 submit 方法所提交的命令,通过所请求的 0 延迟进行安排。schedule 方法中允许出现 0 和负数延迟(但不是周期),并将这些视为一种立即执行的请求。
所有的 schedule 方法都接受相对 延迟和周期作为参数,而不是绝日期。将以 Date 所表示的绝对时间转换成要求的形式很容 易。例如,要安排在某个以后的 Date 运行,可以使用:schedule(task, date.getTime()-System.currentTimeMillis (), TimeUnit.MILLISECONDS)。但是要注意,由于网络时间同步协议、时钟漂移或其他因素的存在,因此相对 延迟的期满日期不必与启用任务的当前 Date 相符。 Executors 类为此包中所提供的 ScheduledExecutorService 实现提 供了便捷的工厂方法。
方法: public ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);
方法解释:创建并执行在给定延迟后启用的 ScheduledFuture。
参数解释: command -- 任务 collection (就是执行任务的集合)
delay -- 最长等待时间
unit -- 参数的时间单位
返回解释: ScheduledFuture<?> -- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在完成后将返回 null
方法: public <V> ScheduledFuture<V> schedule(Callable<V> callable,long delay, TimeUnit unit);
方法解释:创建并执行在给定延迟后启用的 ScheduledFuture。
参数解释: callable -- 要执行的功能
delay -- 最长等待时间
unit -- 参数的时间单位
返回解释: <V> -- 可用于提取结果或取消的 ScheduledFuture
方法: public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,
long period,TimeUnit unit);
方法解释:创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然 后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的任何一个执行 遇到异常,则后续执行都会被取消。否则,只能通过执行程序的取消或终止方法来终止该任务。如果此任务的任何一个执行要花费比 其周期更长的时间,则将推迟后续执行,但不会同时执行。
参数解释: command -- 要执行的任务
initialDelay -- 首次执行的延迟时间
period -- 连续执行之间的周期
unit -- initialDelay 和 period 参数的时间单位
返回解释: ScheduledFuture<?> -- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在完成后将返回 null
方法: public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,
long delay,TimeUnit unit);
方法解释:创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任 务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程序的取消或终止方法来终止该任务。
参数解释: command -- 要执行的任务
initialDelay -- 首次执行的延迟时间
period -- 连续执行之间的周期
unit -- initialDelay 和 period 参数的时间单位
返回解释: ScheduledFuture<?> -- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在完成后将返回 null
4. Iterable迭代器用于循环
4. Iterable迭代器用于循环
5.AbstractEventExecutorGroup
6. AbstractEventExecutorGroup
===========================================================================================================
public abstract class AbstractEventExecutorGroup implements EventExecutorGroup {
/**获取当前下一个事件执行器去执行任务*/
@Override
public Future<?> submit(Runnable task) {
return next().submit(task);
}
/**获取当前下一个事件执行器去执行任务*/
@Override
public <T> Future<T> submit(Runnable task, T result) {
return next().submit(task, result);
}
/**获取当前下一个事件执行器去执行任务*/
@Override
public <T> Future<T> submit(Callable<T> task) {
return next().submit(task);
}
/**获取当前下一个事件执行器 创建并执行在给定延迟后启用的 ScheduledFuture*/
@Override
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
return next().schedule(command, delay, unit);
}
/**获取当前下一个事件执行器 创建并执行在给定延迟后启用的 ScheduledFuture。*/
@Override
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
return next().schedule(callable, delay, unit);
}
/**获取当前下一个事件执行器 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的任何一个执行遇到异常,则后续执行都会被取消。否则,只能通过执行程序的取消或终止方法来终止该任务。如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行。*/
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
return next().scheduleAtFixedRate(command, initialDelay, period, unit);
}
/**获取当前下一个事件执行器 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程序的取消或终止方法来终止该任务。*/
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
return next().scheduleWithFixedDelay(command, initialDelay, delay, unit);
}
/**
默认值 DEFAULT_SHUTDOWN_QUIET_PERIOD = 2
默认值 DEFAULT_SHUTDOWN_TIMEOUT = 15
单位 秒
通知此执行者调用者希望关闭该执行者。 调用此方法后, isShuttingDown()开始返回true ,执行程序准备关闭自身。 与 shutdown()不同,正常关闭可确保在关闭之前“静默期” (通常是几秒钟)内不提交任何任务。 如果在静默期提交任务,则可以 确保任务被接受,静默期将重新开始
*/
@Override
public Future<?> shutdownGracefully() {
return shutdownGracefully(DEFAULT_SHUTDOWN_QUIET_PERIOD, DEFAULT_SHUTDOWN_TIMEOUT, TimeUnit.SECONDS);
}
/**
* @deprecated {@link #shutdownGracefully(long, long, TimeUnit)} or {@link #shutdownGracefully()} instead.
*/
@Override
@Deprecated
public abstract void shutdown();
/**
* 停止并返回一个空的list
*/
@Override
@Deprecated
public List<Runnable> shutdownNow() {
shutdown();
return Collections.emptyList();
}
/**获取当前下一个事件执行器 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。*/
@Override
public <T> List<java.util.concurrent.Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
return next().invokeAll(tasks);
}
/**获取当前下一个事件执行器 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future *列表。
*/
@Override
public <T> List<java.util.concurrent.Future<T>> invokeAll(
Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
return next().invokeAll(tasks, timeout, unit);
}
/**获取当前下一个事件执行器 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future * 列表。
*/
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
return next().invokeAny(tasks);
}
/**获取当前下一个事件执行器 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future * 列表。
*/
@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return next().invokeAny(tasks, timeout, unit);
}
/** 获取当前下一个事件执行器 执行给定的任务*/
@Override
public void execute(Runnable command) {
next().execute(command);
}
}
============================================================================================================
6.MultithreadEventExecutorGroup
7.MultithreadEventExecutorGroup
============================================================================================================ /**EventExecutorGroup实现的抽象基类,可EventExecutorGroup处理多个线程的任务*/
public abstract class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup {
private final EventExecutor[] children;
private final Set<EventExecutor> readonlyChildren;
private final AtomicInteger terminatedChildren = new AtomicInteger();
private final Promise<?> terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);
private final EventExecutorChooserFactory.EventExecutorChooser chooser;
/** nThreads: 默认值为当前系统的cpu盒数X2 */
protected MultithreadEventExecutorGroup(int nThreads, ThreadFactory threadFactory, Object... args) {
this(nThreads, threadFactory == null ? null : new ThreadPerTaskExecutor(threadFactory), args);
}
/** DefaultEventExecutorChooserFactory 事件处理器选择厂
* public static final DefaultEventExecutorChooserFactory INSTANCE =
* new DefaultEventExecutorChooserFactory();
* 根据线程数 和执行器 创建 MultithreadEventExecutorGroup
* args 是啥不知道
*/
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {
this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);
}
/**
* Create a new instance.
*
* @param nThreads 默认值为当前系统的cpu盒数X2
* @param executor 提供一种将任务提交与每个任务将如何运行的机制
* @param chooserFactory 事件处理器选择厂
* @param args
*/
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,
EventExecutorChooserFactory chooserFactory, Object... args) {
//检查线程数
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
}
if (executor == null) {
//默认 创建线程工厂= new DefaultThreadFactory(getClass())
executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}
children = new EventExecutor[nThreads];
for (int i = 0; i < nThreads; i ++) {
boolean success = false;
try {
children[i] = newChild(executor, args);
success = true;
} catch (Exception e) {
// TODO: Think about if this is a good exception type
throw new IllegalStateException("failed to create a child event loop", e);
} finally {
if (!success) {
for (int j = 0; j < i; j ++) {
children[j].shutdownGracefully();
}
for (int j = 0; j < i; j ++) {
EventExecutor e = children[j];
try {
while (!e.isTerminated()) {
e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
}
} catch (InterruptedException interrupted) {
// Let the caller handle the interruption.
Thread.currentThread().interrupt();
break;
}
}
}
}
}
chooser = chooserFactory.newChooser(children);
final FutureListener<Object> terminationListener = new FutureListener<Object>() {
@Override
public void operationComplete(Future<Object> future) throws Exception {
if (terminatedChildren.incrementAndGet() == children.length) {
terminationFuture.setSuccess(null);
}
}
};
for (EventExecutor e: children) {
e.terminationFuture().addListener(terminationListener);
}
Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);
Collections.addAll(childrenSet, children);
readonlyChildren = Collections.unmodifiableSet(childrenSet);
}
/**创建默认的线程生产工厂*/
protected ThreadFactory newDefaultThreadFactory() {
return new DefaultThreadFactory(getClass());
}
@Override
public EventExecutor next() {
return chooser.next();
}
@Override
public Iterator<EventExecutor> iterator() {
return readonlyChildren.iterator();
}
/**
* Return the number of {@link EventExecutor} this implementation uses. This number is the maps
* 1:1 to the threads it use.
*/
public final int executorCount() {
return children.length;
}
/**
* Create a new EventExecutor which will later then accessible via the {@link #next()} method. This method will be
* called for each thread that will serve this {@link MultithreadEventExecutorGroup}.
*
*/
protected abstract EventExecutor newChild(Executor executor, Object... args) throws Exception;
@Override
public Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) {
for (EventExecutor l: children) {
l.shutdownGracefully(quietPeriod, timeout, unit);
}
return terminationFuture();
}
@Override
public Future<?> terminationFuture() {
return terminationFuture;
}
@Override
@Deprecated
public void shutdown() {
for (EventExecutor l: children) {
l.shutdown();
}
}
@Override
public boolean isShuttingDown() {
for (EventExecutor l: children) {
if (!l.isShuttingDown()) {
return false;
}
}
return true;
}
@Override
public boolean isShutdown() {
for (EventExecutor l: children) {
if (!l.isShutdown()) {
return false;
}
}
return true;
}
@Override
public boolean isTerminated() {
for (EventExecutor l: children) {
if (!l.isTerminated()) {
return false;
}
}
return true;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long deadline = System.nanoTime() + unit.toNanos(timeout);
loop: for (EventExecutor l: children) {
for (;;) {
long timeLeft = deadline - System.nanoTime();
if (timeLeft <= 0) {
break loop;
}
if (l.awaitTermination(timeLeft, TimeUnit.NANOSECONDS)) {
break;
}
}
}
return isTerminated();
}
}
============================================================================================================
7.EventLoopGroup
public interface EventLoopGroup extends EventExecutorGroup {
/**
* Return the next {@link EventLoop} to use
*/
@Override
EventLoop next();
/**
* Register a {@link Channel} with this {@link EventLoop}. The returned {@link ChannelFuture}
* will get notified once the registration was complete.
*/
ChannelFuture register(Channel channel);
/**
* Register a {@link Channel} with this {@link EventLoop} using a {@link ChannelFuture}. The passed
* {@link ChannelFuture} will get notified once the registration was complete and also will get returned.
*/
ChannelFuture register(ChannelPromise promise);
@Deprecated
ChannelFuture register(Channel channel, ChannelPromise promise);
}
8.MultithreadEventLoopGroup
public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(MultithreadEventLoopGroup.class);
/** 默认静态初始化线程数 为 cpu盒数 * 2 */
private static final int DEFAULT_EVENT_LOOP_THREADS;
static {
DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
"io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.eventLoopThreads: {}", DEFAULT_EVENT_LOOP_THREADS);
}
}
/**
* 初始化线程数 并且根据线程数和执行器 调用父类的构造
* args是什么不理解
*/
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
/**
* @see MultithreadEventExecutorGroup#MultithreadEventExecutorGroup(int, ThreadFactory, Object...)
*/
protected MultithreadEventLoopGroup(int nThreads, ThreadFactory threadFactory, Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, threadFactory, args);
}
/**
* @see MultithreadEventExecutorGroup#MultithreadEventExecutorGroup(int, Executor,
* EventExecutorChooserFactory, Object...)
*/
protected MultithreadEventLoopGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory,
Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, chooserFactory, args);
}
@Override
protected ThreadFactory newDefaultThreadFactory() {
return new DefaultThreadFactory(getClass(), Thread.MAX_PRIORITY);
}
@Override
public EventLoop next() {
return (EventLoop) super.next();
}
@Override
protected abstract EventLoop newChild(Executor executor, Object... args) throws Exception;
@Override
public ChannelFuture register(Channel channel) {
return next().register(channel);
}
@Override
public ChannelFuture register(ChannelPromise promise) {
return next().register(promise);
}
@Deprecated
@Override
public ChannelFuture register(Channel channel, ChannelPromise promise) {
return next().register(channel, promise);
}
}
9.DefaultThreadFactory
9.DefaultThreadFactory
============================================================================================================
package io.netty.util.concurrent;
import io.netty.util.internal.StringUtil;
import java.util.Locale;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 一个默认的线程工厂
*/
public class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolId = new AtomicInteger();
private final AtomicInteger nextId = new AtomicInteger();
private final String prefix;
private final boolean daemon;
private final int priority;
protected final ThreadGroup threadGroup;
public DefaultThreadFactory(Class<?> poolType) {
//Thread.NORM_PRIORITY 线程权限 默认为 5
this(poolType, false, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(String poolName) {
this(poolName, false, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(Class<?> poolType, boolean daemon) {
this(poolType, daemon, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(String poolName, boolean daemon) {
this(poolName, daemon, Thread.NORM_PRIORITY);
}
public DefaultThreadFactory(Class<?> poolType, int priority) {
this(poolType, false, priority);
}
public DefaultThreadFactory(String poolName, int priority) {
this(poolName, false, priority);
}
public DefaultThreadFactory(Class<?> poolType, boolean daemon, int priority) {
this(toPoolName(poolType), daemon, priority);
}
public static String toPoolName(Class<?> poolType) {
if (poolType == null) {
throw new NullPointerException("poolType");
}
String poolName = StringUtil.simpleClassName(poolType);
switch (poolName.length()) {
case 0:
return "unknown";
case 1:
return poolName.toLowerCase(Locale.US);
default:
if (Character.isUpperCase(poolName.charAt(0)) && Character.isLowerCase(poolName.charAt(1))) {
return Character.toLowerCase(poolName.charAt(0)) + poolName.substring(1);
} else {
return poolName;
}
}
}
public DefaultThreadFactory(String poolName, boolean daemon, int priority, ThreadGroup threadGroup) {
if (poolName == null) {
throw new NullPointerException("poolName");
}
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
throw new IllegalArgumentException(
"priority: " + priority + " (expected: Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY)");
}
prefix = poolName + '-' + poolId.incrementAndGet() + '-';
this.daemon = daemon;
this.priority = priority;
this.threadGroup = threadGroup;
}
public DefaultThreadFactory(String poolName, boolean daemon, int priority) {
this(poolName, daemon, priority, System.getSecurityManager() == null ?
Thread.currentThread().getThreadGroup() : System.getSecurityManager().getThreadGroup());
}
@Override
public Thread newThread(Runnable r) {
Thread t = newThread(FastThreadLocalRunnable.wrap(r), prefix + nextId.incrementAndGet());
try {
if (t.isDaemon() != daemon) {
t.setDaemon(daemon);
}
if (t.getPriority() != priority) {
t.setPriority(priority);
}
} catch (Exception ignored) {
// Doesn't matter even if failed to set.
}
return t;
}
protected Thread newThread(Runnable r, String name) {
return new FastThreadLocalThread(threadGroup, r, name);
}
}
10.NioEventLoopGroup
public class NioEventLoopGroup extends MultithreadEventLoopGroup {
/**
* 初始化 NioEventLoopGroup 传入默认线程数0
*/
public NioEventLoopGroup() {
this(0);
}
/**
* 根据线程数 初始化 NioEventLoopGroup
*/
public NioEventLoopGroup(int nThreads) {
this(nThreads, (Executor) null);
}
/**
* 根据线程数和 线程工厂 初始化 NioEventLoopGroup
*/
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory) {
this(nThreads, threadFactory, SelectorProvider.provider());
}
/**
* 根据线程数和 执行器 权限 初始化NioEventLoopGroup
*/
public NioEventLoopGroup(int nThreads, Executor executor) {
this(nThreads, executor, SelectorProvider.provider());
}
/**
* 根据线程数和 执行器 初始化 权限 初始化NioEventLoopGroup
* DefaultSelectStrategyFactory.INSTANCE ->初始化默认的选择策略的工厂
*/
public NioEventLoopGroup(
int nThreads, ThreadFactory threadFactory, final SelectorProvider selectorProvider) {
this(nThreads, threadFactory, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}
/**
* 根据线程数和 执行器 初始化 权限 工厂 初始化NioEventLoopGroup
* RejectedExecutionHandlers.reject() -> 不了解
* supper 父类MultithreadEventLoopGroup
*/
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory,
final SelectorProvider selectorProvider, final SelectStrategyFactory selectStrategyFactory) {
super(nThreads, threadFactory, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
public NioEventLoopGroup(
int nThreads, Executor executor, final SelectorProvider selectorProvider) {
this(nThreads, executor, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}
public NioEventLoopGroup(int nThreads, Executor executor, final SelectorProvider selectorProvider,
final SelectStrategyFactory selectStrategyFactory) {
super(nThreads, executor, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject());
}
public NioEventLoopGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory,
final SelectorProvider selectorProvider,
final SelectStrategyFactory selectStrategyFactory) {
super(nThreads, executor, chooserFactory, selectorProvider, selectStrategyFactory,
RejectedExecutionHandlers.reject());
}
public NioEventLoopGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory,
final SelectorProvider selectorProvider,
final SelectStrategyFactory selectStrategyFactory,
final RejectedExecutionHandler rejectedExecutionHandler) {
super(nThreads, executor, chooserFactory, selectorProvider, selectStrategyFactory, rejectedExecutionHandler);
}
/**
* Sets the percentage of the desired amount of time spent for I/O in the child event loops. The default value is
* {@code 50}, which means the event loop will try to spend the same amount of time for I/O as for non-I/O tasks.
*/
public void setIoRatio(int ioRatio) {
for (EventExecutor e: this) {
((NioEventLoop) e).setIoRatio(ioRatio);
}
}
/**
* Replaces the current {@link Selector}s of the child event loops with newly created {@link Selector}s to work
* around the infamous epoll 100% CPU bug.
*/
public void rebuildSelectors() {
for (EventExecutor e: this) {
((NioEventLoop) e).rebuildSelector();
}
}
@Override
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
return new NioEventLoop(this, executor, (SelectorProvider) args[0],
((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
}
}
11.EventExecutorGroup
EventExecutorGroup
接口解释:EventExecutorGroup负责通过其next()方法提供要使用的EventExecutor 。 除此之外,它还负责处理其生命周期,并允许以 全局方式关闭它们
方法: boolean isShuttingDown();
方法解释:当且仅当由该EventExecutorGroup管理的所有EventExecutor正常关闭或已关闭时,才返回true
方法: Future<?> shutdownGracefully();
方法解释:
方法: Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit);
方法解释:通知此执行者调用者希望关闭该执行者。 调用此方法后, isShuttingDown()开始返回true ,执行程序准备关闭自身。 与 shutdown()不同,正常关闭可确保在关闭之前“静默期” (通常是几秒钟)内不提交任何任务。 如果在静默期提交任务,则可以 确保任务被接受,静默期将重新开始。
参数解释: quietPeriod -- quietPeriod –文档中所述的安静期间(空闲时间)
timeout -- 等待执行者为{@linkplain #shutdown()} 的最长时间,而不管任务是否在安静期间提交(超时时间)
unit -- quietPeriod和timeout的时间单位
返回解释:表示任务等待完成的 Future
方法: Future<?> terminationFuture();
方法解释:返回由该EventExecutorGroup管理的所有EventExecutor终止时通知的Future
方法: EventExecutor next();
方法解释:返回下一个事件执行器
返回解释:事件执行器
方法:void shutdown();
方法解释:继承ScheduledExecutorService的shutdown()用来关闭事件组,已不推荐使用
方法:List<Runnable> shutdownNow();
方法解释:继承ScheduledExecutorService的shutdown()用来关闭事件组,已不推荐使用
返回解释:异步任务集合
方法:Iterator<EventExecutor> iterator();
方法解释:事件执行器迭代器
方法: <T> Future<T> submit(Callable<T> task);
方法解释:提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
参数解释: task -- 要提交的任务
返回解释: Future -- 表示任务等待完成的 Future
方法: Future<?> submit(Runnable task);
方法解释:提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
参数解释: task -- 要提交的任务
返回解释: Future -- 表示任务等待完成的 Future
方法: <T> Future<T> submit(Runnable task, T result);
方法解释:提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
参数解释: task -- 要提交的任务
result -- 返回的结果
返回解释: Future -- 表示任务等待完成的 Future
方法: public ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);
方法解释:创建并执行在给定延迟后启用的 ScheduledFuture。
参数解释: command -- 任务 collection (就是执行任务的集合)
delay -- 最长等待时间
unit -- 参数的时间单位
返回解释: ScheduledFuture<?> -- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在完成后将返回 null
方法: public <V> ScheduledFuture<V> schedule(Callable<V> callable,long delay, TimeUnit unit);
方法解释:创建并执行在给定延迟后启用的 ScheduledFuture。
参数解释: callable -- 要执行的功能
delay -- 最长等待时间
unit -- 参数的时间单位
返回解释: <V> -- 可用于提取结果或取消的 ScheduledFuture
方法: public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,
long period,TimeUnit unit);
方法解释:创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然 后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的任何一个执行 遇到异常,则后续执行都会被取消。否则,只能通过执行程序的取消或终止方法来终止该任务。如果此任务的任何一个执行要花费比 其周期更长的时间,则将推迟后续执行,但不会同时执行。
参数解释: command -- 要执行的任务
initialDelay -- 首次执行的延迟时间
period -- 连续执行之间的周期
unit -- initialDelay 和 period 参数的时间单位
返回解释: ScheduledFuture<?> -- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在完成后将返回 null
方法: public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,
long delay,TimeUnit unit);
方法解释:创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任 务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程序的取消或终止方法来终止该任务。
参数解释: command -- 要执行的任务
initialDelay -- 首次执行的延迟时间
period -- 连续执行之间的周期
unit -- initialDelay 和 period 参数的时间单位
返回解释: ScheduledFuture<?> -- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在完成后将返回 null
12.SelectorProvider
public abstract class SelectorProvider {
//线程锁
private static final Object lock = new Object();
private static SelectorProvider provider = null;
protected SelectorProvider() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new RuntimePermission("selectorProvider"));
}
private static boolean loadProviderFromProperty() {
String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
if (cn == null)
return false;
try {
Class<?> c = Class.forName(cn, true,
ClassLoader.getSystemClassLoader());
provider = (SelectorProvider)c.newInstance();
return true;
} catch (ClassNotFoundException x) {
throw new ServiceConfigurationError(null, x);
} catch (IllegalAccessException x) {
throw new ServiceConfigurationError(null, x);
} catch (InstantiationException x) {
throw new ServiceConfigurationError(null, x);
} catch (SecurityException x) {
throw new ServiceConfigurationError(null, x);
}
}
private static boolean loadProviderAsService() {
ServiceLoader<SelectorProvider> sl =
ServiceLoader.load(SelectorProvider.class,
ClassLoader.getSystemClassLoader());
Iterator<SelectorProvider> i = sl.iterator();
for (;;) {
try {
if (!i.hasNext())
return false;
provider = i.next();
return true;
} catch (ServiceConfigurationError sce) {
if (sce.getCause() instanceof SecurityException) {
// Ignore the security exception, try the next provider
continue;
}
throw sce;
}
}
}
/**
* Returns the system-wide default selector provider for this invocation of
* the Java virtual machine.
*
* <p> The first invocation of this method locates the default provider
* object as follows: </p>
*
* <ol>
*
* <li><p> If the system property
* <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is
* taken to be the fully-qualified name of a concrete provider class.
* The class is loaded and instantiated; if this process fails then an
* unspecified error is thrown. </p></li>
*
* <li><p> If a provider class has been installed in a jar file that is
* visible to the system class loader, and that jar file contains a
* provider-configuration file named
* <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource
* directory <tt>META-INF/services</tt>, then the first class name
* specified in that file is taken. The class is loaded and
* instantiated; if this process fails then an unspecified error is
* thrown. </p></li>
*
* <li><p> Finally, if no provider has been specified by any of the above
* means then the system-default provider class is instantiated and the
* result is returned. </p></li>
*
* </ol>
*
* <p> Subsequent invocations of this method return the provider that was
* returned by the first invocation. </p>
*
* @return The system-wide default selector provider
*/
public static SelectorProvider provider() {
synchronized (lock) {
if (provider != null)
return provider;
return AccessController.doPrivileged(
new PrivilegedAction<SelectorProvider>() {
public SelectorProvider run() {
if (loadProviderFromProperty())
return provider;
if (loadProviderAsService())
return provider;
provider = sun.nio.ch.DefaultSelectorProvider.create();
return provider;
}
});
}
}
/**
* Opens a datagram channel.
*
* @return The new channel
*
* @throws IOException
* If an I/O error occurs
*/
public abstract DatagramChannel openDatagramChannel()
throws IOException;
/**
* Opens a datagram channel.
*
* @param family
* The protocol family
*
* @return A new datagram channel
*
* @throws UnsupportedOperationException
* If the specified protocol family is not supported
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
throws IOException;
/**
* Opens a pipe.
*
* @return The new pipe
*
* @throws IOException
* If an I/O error occurs
*/
public abstract Pipe openPipe()
throws IOException;
/**
* Opens a selector.
*
* @return The new selector
*
* @throws IOException
* If an I/O error occurs
*/
public abstract AbstractSelector openSelector()
throws IOException;
/**
* Opens a server-socket channel.
*
* @return The new channel
*
* @throws IOException
* If an I/O error occurs
*/
public abstract ServerSocketChannel openServerSocketChannel()
throws IOException;
/**
* Opens a socket channel.
*
* @return The new channel
*
* @throws IOException
* If an I/O error occurs
*/
public abstract SocketChannel openSocketChannel()
throws IOException;
/**
* Returns the channel inherited from the entity that created this
* Java virtual machine.
*
* <p> On many operating systems a process, such as a Java virtual
* machine, can be started in a manner that allows the process to
* inherit a channel from the entity that created the process. The
* manner in which this is done is system dependent, as are the
* possible entities to which the channel may be connected. For example,
* on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
* start programs to service requests when a request arrives on an
* associated network port. In this example, the process that is started,
* inherits a channel representing a network socket.
*
* <p> In cases where the inherited channel represents a network socket
* then the {@link java.nio.channels.Channel Channel} type returned
* by this method is determined as follows:
*
* <ul>
*
* <li><p> If the inherited channel represents a stream-oriented connected
* socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
* returned. The socket channel is, at least initially, in blocking
* mode, bound to a socket address, and connected to a peer.
* </p></li>
*
* <li><p> If the inherited channel represents a stream-oriented listening
* socket then a {@link java.nio.channels.ServerSocketChannel
* ServerSocketChannel} is returned. The server-socket channel is, at
* least initially, in blocking mode, and bound to a socket address.
* </p></li>
*
* <li><p> If the inherited channel is a datagram-oriented socket
* then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
* returned. The datagram channel is, at least initially, in blocking
* mode, and bound to a socket address.
* </p></li>
*
* </ul>
*
* <p> In addition to the network-oriented channels described, this method
* may return other kinds of channels in the future.
*
* <p> The first invocation of this method creates the channel that is
* returned. Subsequent invocations of this method return the same
* channel. </p>
*
* @return The inherited channel, if any, otherwise <tt>null</tt>.
*
* @throws IOException
* If an I/O error occurs
*
* @throws SecurityException
* If a security manager has been installed and it denies
* {@link RuntimePermission}<tt>("inheritedChannel")</tt>
*
* @since 1.5
*/
public Channel inheritedChannel() throws IOException {
return null;
}
}
13.DefaultSelectStrategyFactory
public final class DefaultSelectStrategyFactory implements SelectStrategyFactory {
//创建选择策略的工厂
public static final SelectStrategyFactory INSTANCE = new DefaultSelectStrategyFactory();
private DefaultSelectStrategyFactory() { }
@Override
public SelectStrategy newSelectStrategy() {
return DefaultSelectStrategy.INSTANCE;
}
}
14.DefaultEventExecutorChooserFactory
/** 事件处理器选择工厂*/
@UnstableApi
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {
public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();
private DefaultEventExecutorChooserFactory() { }
@SuppressWarnings("unchecked")
@Override
public EventExecutorChooser newChooser(EventExecutor[] executors) {
if (isPowerOfTwo(executors.length)) {
return new PowerOfTwoEventExecutorChooser(executors);
} else {
return new GenericEventExecutorChooser(executors);
}
}
/** 获取事件执行器的长度 比较是否是2的倍数 */
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
}
/** 如果是2的倍数*/
private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
return executors[idx.getAndIncrement() & executors.length - 1];
}
}
/** 如果不是2的倍数*/
private static final class GenericEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
GenericEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}
}
}
15.GlobalEventExecutor
public final class GlobalEventExecutor extends AbstractScheduledEventExecutor {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(GlobalEventExecutor.class);
private static final long SCHEDULE_QUIET_PERIOD_INTERVAL = TimeUnit.SECONDS.toNanos(1);
public static final GlobalEventExecutor INSTANCE = new GlobalEventExecutor();
final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
final ScheduledFutureTask<Void> quietPeriodTask = new ScheduledFutureTask<Void>(
this, Executors.<Void>callable(new Runnable() {
@Override
public void run() {
}
}, null), ScheduledFutureTask.deadlineNanos(SCHEDULE_QUIET_PERIOD_INTERVAL), -SCHEDULE_QUIET_PERIOD_INTERVAL);
final ThreadFactory threadFactory =
new DefaultThreadFactory(DefaultThreadFactory.toPoolName(getClass()), false, Thread.NORM_PRIORITY, null);
private final TaskRunner taskRunner = new TaskRunner();
private final AtomicBoolean started = new AtomicBoolean();
volatile Thread thread;
private final Future<?> terminationFuture = new FailedFuture<Object>(this, new UnsupportedOperationException());
private GlobalEventExecutor() {
scheduledTaskQueue().add(quietPeriodTask);
}
Runnable takeTask() {
BlockingQueue<Runnable> taskQueue = this.taskQueue;
for (;;) {
ScheduledFutureTask<?> scheduledTask = peekScheduledTask();
if (scheduledTask == null) {
Runnable task = null;
try {
task = taskQueue.take();
} catch (InterruptedException e) {
// Ignore
}
return task;
} else {
long delayNanos = scheduledTask.delayNanos();
Runnable task;
if (delayNanos > 0) {
try {
task = taskQueue.poll(delayNanos, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
// Waken up.
return null;
}
} else {
task = taskQueue.poll();
}
if (task == null) {
fetchFromScheduledTaskQueue();
task = taskQueue.poll();
}
if (task != null) {
return task;
}
}
}
}
private void fetchFromScheduledTaskQueue() {
long nanoTime = AbstractScheduledEventExecutor.nanoTime();
Runnable scheduledTask = pollScheduledTask(nanoTime);
while (scheduledTask != null) {
taskQueue.add(scheduledTask);
scheduledTask = pollScheduledTask(nanoTime);
}
}
public int pendingTasks() {
return taskQueue.size();
}
private void addTask(Runnable task) {
if (task == null) {
throw new NullPointerException("task");
}
taskQueue.add(task);
}
@Override
public boolean inEventLoop(Thread thread) {
return thread == this.thread;
}
@Override
public Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) {
return terminationFuture();
}
@Override
public Future<?> terminationFuture() {
return terminationFuture;
}
@Override
@Deprecated
public void shutdown() {
throw new UnsupportedOperationException();
}
@Override
public boolean isShuttingDown() {
return false;
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) {
return false;
}
public boolean awaitInactivity(long timeout, TimeUnit unit) throws InterruptedException {
if (unit == null) {
throw new NullPointerException("unit");
}
final Thread thread = this.thread;
if (thread == null) {
throw new IllegalStateException("thread was not started");
}
thread.join(unit.toMillis(timeout));
return !thread.isAlive();
}
@Override
public void execute(Runnable task) {
if (task == null) {
throw new NullPointerException("task");
}
addTask(task);
if (!inEventLoop()) {
startThread();
}
}
private void startThread() {
if (started.compareAndSet(false, true)) {
Thread t = threadFactory.newThread(taskRunner);
thread = t;
t.start();
}
}
final class TaskRunner implements Runnable {
@Override
public void run() {
for (;;) {
Runnable task = takeTask();
if (task != null) {
try {
task.run();
} catch (Throwable t) {
logger.warn("Unexpected exception from the global event executor: ", t);
}
if (task != quietPeriodTask) {
continue;
}
}
Queue<ScheduledFutureTask<?>> scheduledTaskQueue = GlobalEventExecutor.this.scheduledTaskQueue;
if (taskQueue.isEmpty() && (scheduledTaskQueue == null || scheduledTaskQueue.size() == 1)) {
boolean stopped = started.compareAndSet(true, false);
assert stopped;
if (taskQueue.isEmpty() && (scheduledTaskQueue == null || scheduledTaskQueue.size() == 1)) {
break;
}
if (!started.compareAndSet(false, true)) {
break;
}
}
}
}
}
}
16.DefaultPromise
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultPromise.class);
private static final InternalLogger rejectedExecutionLogger =
InternalLoggerFactory.getInstance(DefaultPromise.class.getName() + ".rejectedExecution");
// 可以嵌套的Listener的最大层数,可见最大值为8
private static final int MAX_LISTENER_STACK_DEPTH = Math.min(8,
SystemPropertyUtil.getInt("io.netty.defaultPromise.maxListenerStackDepth", 8));
//result字段由使用RESULT_UPDATER更新
@SuppressWarnings("rawtypes")
private static final AtomicReferenceFieldUpdater<DefaultPromise, Object> RESULT_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(DefaultPromise.class, Object.class, "result");
private static final Signal SUCCESS = Signal.valueOf(DefaultPromise.class, "SUCCESS");
private static final Signal UNCANCELLABLE = Signal.valueOf(DefaultPromise.class, "UNCANCELLABLE");
private static final CauseHolder CANCELLATION_CAUSE_HOLDER = new CauseHolder(ThrowableUtil.unknownStackTrace(
new CancellationException(), DefaultPromise.class, "cancel(...)"));
private volatile Object result;
private final EventExecutor executor;
private short waiters;
private boolean notifyingListeners;
public DefaultPromise(EventExecutor executor) {
this.executor = checkNotNull(executor, "executor");
}
protected DefaultPromise() {
executor = null;
}
@Override
public Promise<V> setSuccess(V result) {
if (setSuccess0(result)) {
notifyListeners();
return this;
}
throw new IllegalStateException("complete already: " + this);
}
@Override
public boolean trySuccess(V result) {
if (setSuccess0(result)) {
notifyListeners();
return true;
}
return false;
}
@Override
public Promise<V> setFailure(Throwable cause) {
if (setFailure0(cause)) {
notifyListeners();
return this;
}
throw new IllegalStateException("complete already: " + this, cause);
}
@Override
public boolean tryFailure(Throwable cause) {
if (setFailure0(cause)) {
notifyListeners();
return true;
}
return false;
}
@Override
public boolean setUncancellable() {
if (RESULT_UPDATER.compareAndSet(this, null, UNCANCELLABLE)) {
return true;
}
Object result = this.result;
return !isDone0(result) || !isCancelled0(result);
}
@Override
public boolean isSuccess() {
Object result = this.result;
return result != null && result != UNCANCELLABLE && !(result instanceof CauseHolder);
}
@Override
public boolean isCancellable() {
return result == null;
}
@Override
public Throwable cause() {
Object result = this.result;
return (result instanceof CauseHolder) ? ((CauseHolder) result).cause : null;
}
@Override
public Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener) {
checkNotNull(listener, "listener");
synchronized (this) {
addListener0(listener);
}
if (isDone()) {
notifyListeners();
}
return this;
}
@Override
public Promise<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners) {
checkNotNull(listeners, "listeners");
synchronized (this) {
for (GenericFutureListener<? extends Future<? super V>> listener : listeners) {
if (listener == null) {
break;
}
addListener0(listener);
}
}
if (isDone()) {
notifyListeners();
}
return this;
}
@Override
public Promise<V> removeListener(final GenericFutureListener<? extends Future<? super V>> listener) {
checkNotNull(listener, "listener");
synchronized (this) {
removeListener0(listener);
}
return this;
}
@Override
public Promise<V> removeListeners(final GenericFutureListener<? extends Future<? super V>>... listeners) {
checkNotNull(listeners, "listeners");
synchronized (this) {
for (GenericFutureListener<? extends Future<? super V>> listener : listeners) {
if (listener == null) {
break;
}
removeListener0(listener);
}
}
return this;
}
@Override
public Promise<V> await() throws InterruptedException {
if (isDone()) {
return this;
}
if (Thread.interrupted()) {
throw new InterruptedException(toString());
}
checkDeadLock();
synchronized (this) {
while (!isDone()) {
incWaiters();
try {
wait();
} finally {
decWaiters();
}
}
}
return this;
}
@Override
public Promise<V> awaitUninterruptibly() {
if (isDone()) {
return this;
}
checkDeadLock();
boolean interrupted = false;
synchronized (this) {
while (!isDone()) {
incWaiters();
try {
wait();
} catch (InterruptedException e) {
interrupted = true;
} finally {
decWaiters();
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
return this;
}
@Override
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return await0(unit.toNanos(timeout), true);
}
@Override
public boolean await(long timeoutMillis) throws InterruptedException {
return await0(MILLISECONDS.toNanos(timeoutMillis), true);
}
@Override
public boolean awaitUninterruptibly(long timeout, TimeUnit unit) {
try {
return await0(unit.toNanos(timeout), false);
} catch (InterruptedException e) {
throw new InternalError();
}
}
@Override
public boolean awaitUninterruptibly(long timeoutMillis) {
try {
return await0(MILLISECONDS.toNanos(timeoutMillis), false);
} catch (InterruptedException e) {
throw new InternalError();
}
}
@SuppressWarnings("unchecked")
@Override
public V getNow() {
Object result = this.result;
if (result instanceof CauseHolder || result == SUCCESS) {
return null;
}
return (V) result;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if (RESULT_UPDATER.compareAndSet(this, null, CANCELLATION_CAUSE_HOLDER)) {
checkNotifyWaiters();
notifyListeners();
return true;
}
return false;
}
@Override
public boolean isCancelled() {
return isCancelled0(result);
}
@Override
public boolean isDone() {
return isDone0(result);
}
@Override
public Promise<V> sync() throws InterruptedException {
await();
rethrowIfFailed();
return this;
}
@Override
public Promise<V> syncUninterruptibly() {
awaitUninterruptibly();
rethrowIfFailed();
return this;
}
@Override
public String toString() {
return toStringBuilder().toString();
}
protected StringBuilder toStringBuilder() {
StringBuilder buf = new StringBuilder(64)
.append(StringUtil.simpleClassName(this))
.append('@')
.append(Integer.toHexString(hashCode()));
Object result = this.result;
if (result == SUCCESS) {
buf.append("(success)");
} else if (result == UNCANCELLABLE) {
buf.append("(uncancellable)");
} else if (result instanceof CauseHolder) {
buf.append("(failure: ")
.append(((CauseHolder) result).cause)
.append(')');
} else if (result != null) {
buf.append("(success: ")
.append(result)
.append(')');
} else {
buf.append("(incomplete)");
}
return buf;
}
protected EventExecutor executor() {
return executor;
}
protected void checkDeadLock() {
EventExecutor e = executor();
if (e != null && e.inEventLoop()) {
throw new BlockingOperationException(toString());
}
}
protected static void notifyListener(
EventExecutor eventExecutor, final Future<?> future, final GenericFutureListener<?> listener) {
checkNotNull(eventExecutor, "eventExecutor");
checkNotNull(future, "future");
checkNotNull(listener, "listener");
notifyListenerWithStackOverFlowProtection(eventExecutor, future, listener);
}
private void notifyListeners() {
EventExecutor executor = executor();
if (executor.inEventLoop()) {
final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get();
final int stackDepth = threadLocals.futureListenerStackDepth();
if (stackDepth < MAX_LISTENER_STACK_DEPTH) {
threadLocals.setFutureListenerStackDepth(stackDepth + 1);
try {
notifyListenersNow();
} finally {
threadLocals.setFutureListenerStackDepth(stackDepth);
}
return;
}
}
safeExecute(executor, new Runnable() {
@Override
public void run() {
notifyListenersNow();
}
});
}
private static void notifyListenerWithStackOverFlowProtection(final EventExecutor executor,
final Future<?> future,
final GenericFutureListener<?> listener) {
if (executor.inEventLoop()) {
final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get();
final int stackDepth = threadLocals.futureListenerStackDepth();
if (stackDepth < MAX_LISTENER_STACK_DEPTH) {
threadLocals.setFutureListenerStackDepth(stackDepth + 1);
try {
notifyListener0(future, listener);
} finally {
threadLocals.setFutureListenerStackDepth(stackDepth);
}
return;
}
}
safeExecute(executor, new Runnable() {
@Override
public void run() {
notifyListener0(future, listener);
}
});
}
private void notifyListenersNow() {
Object listeners;
synchronized (this) {
if (notifyingListeners || this.listeners == null) {
return;
}
notifyingListeners = true;
listeners = this.listeners;
this.listeners = null;
}
for (;;) {
if (listeners instanceof DefaultFutureListeners) {
notifyListeners0((DefaultFutureListeners) listeners);
} else {
notifyListener0(this, (GenericFutureListener<?>) listeners);
}
synchronized (this) {
if (this.listeners == null) {
// Nothing can throw from within this method, so setting notifyingListeners back to false does not
// need to be in a finally block.
notifyingListeners = false;
return;
}
listeners = this.listeners;
this.listeners = null;
}
}
}
private void notifyListeners0(DefaultFutureListeners listeners) {
GenericFutureListener<?>[] a = listeners.listeners();
int size = listeners.size();
for (int i = 0; i < size; i ++) {
notifyListener0(this, a[i]);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void notifyListener0(Future future, GenericFutureListener l) {
try {
l.operationComplete(future);
} catch (Throwable t) {
logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationComplete()", t);
}
}
private void addListener0(GenericFutureListener<? extends Future<? super V>> listener) {
if (listeners == null) {
listeners = listener;
} else if (listeners instanceof DefaultFutureListeners) {
((DefaultFutureListeners) listeners).add(listener);
} else {
listeners = new DefaultFutureListeners((GenericFutureListener<?>) listeners, listener);
}
}
private void removeListener0(GenericFutureListener<? extends Future<? super V>> listener) {
if (listeners instanceof DefaultFutureListeners) {
((DefaultFutureListeners) listeners).remove(listener);
} else if (listeners == listener) {
listeners = null;
}
}
private boolean setSuccess0(V result) {
return setValue0(result == null ? SUCCESS : result);
}
private boolean setFailure0(Throwable cause) {
return setValue0(new CauseHolder(checkNotNull(cause, "cause")));
}
private boolean setValue0(Object objResult) {
if (RESULT_UPDATER.compareAndSet(this, null, objResult) ||
RESULT_UPDATER.compareAndSet(this, UNCANCELLABLE, objResult)) {
checkNotifyWaiters();
return true;
}
return false;
}
private synchronized void checkNotifyWaiters() {
if (waiters > 0) {
notifyAll();
}
}
private void incWaiters() {
if (waiters == Short.MAX_VALUE) {
throw new IllegalStateException("too many waiters: " + this);
}
++waiters;
}
private void decWaiters() {
--waiters;
}
private void rethrowIfFailed() {
Throwable cause = cause();
if (cause == null) {
return;
}
PlatformDependent.throwException(cause);
}
private boolean await0(long timeoutNanos, boolean interruptable) throws InterruptedException {
if (isDone()) {
return true;
}
if (timeoutNanos <= 0) {
return isDone();
}
if (interruptable && Thread.interrupted()) {
throw new InterruptedException(toString());
}
checkDeadLock();
long startTime = System.nanoTime();
long waitTime = timeoutNanos;
boolean interrupted = false;
try {
for (;;) {
synchronized (this) {
if (isDone()) {
return true;
}
incWaiters();
try {
wait(waitTime / 1000000, (int) (waitTime % 1000000));
} catch (InterruptedException e) {
if (interruptable) {
throw e;
} else {
interrupted = true;
}
} finally {
decWaiters();
}
}
if (isDone()) {
return true;
} else {
waitTime = timeoutNanos - (System.nanoTime() - startTime);
if (waitTime <= 0) {
return isDone();
}
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
@SuppressWarnings("unchecked")
void notifyProgressiveListeners(final long progress, final long total) {
final Object listeners = progressiveListeners();
if (listeners == null) {
return;
}
final ProgressiveFuture<V> self = (ProgressiveFuture<V>) this;
EventExecutor executor = executor();
if (executor.inEventLoop()) {
if (listeners instanceof GenericProgressiveFutureListener[]) {
notifyProgressiveListeners0(
self, (GenericProgressiveFutureListener<?>[]) listeners, progress, total);
} else {
notifyProgressiveListener0(
self, (GenericProgressiveFutureListener<ProgressiveFuture<V>>) listeners, progress, total);
}
} else {
if (listeners instanceof GenericProgressiveFutureListener[]) {
final GenericProgressiveFutureListener<?>[] array =
(GenericProgressiveFutureListener<?>[]) listeners;
safeExecute(executor, new Runnable() {
@Override
public void run() {
notifyProgressiveListeners0(self, array, progress, total);
}
});
} else {
final GenericProgressiveFutureListener<ProgressiveFuture<V>> l =
(GenericProgressiveFutureListener<ProgressiveFuture<V>>) listeners;
safeExecute(executor, new Runnable() {
@Override
public void run() {
notifyProgressiveListener0(self, l, progress, total);
}
});
}
}
}
private synchronized Object progressiveListeners() {
Object listeners = this.listeners;
if (listeners == null) {
return null;
}
if (listeners instanceof DefaultFutureListeners) {
DefaultFutureListeners dfl = (DefaultFutureListeners) listeners;
int progressiveSize = dfl.progressiveSize();
switch (progressiveSize) {
case 0:
return null;
case 1:
for (GenericFutureListener<?> l: dfl.listeners()) {
if (l instanceof GenericProgressiveFutureListener) {
return l;
}
}
return null;
}
GenericFutureListener<?>[] array = dfl.listeners();
GenericProgressiveFutureListener<?>[] copy = new GenericProgressiveFutureListener[progressiveSize];
for (int i = 0, j = 0; j < progressiveSize; i ++) {
GenericFutureListener<?> l = array[i];
if (l instanceof GenericProgressiveFutureListener) {
copy[j ++] = (GenericProgressiveFutureListener<?>) l;
}
}
return copy;
} else if (listeners instanceof GenericProgressiveFutureListener) {
return listeners;
} else {
// Only one listener was added and it's not a progressive listener.
return null;
}
}
private static void notifyProgressiveListeners0(
ProgressiveFuture<?> future, GenericProgressiveFutureListener<?>[] listeners, long progress, long total) {
for (GenericProgressiveFutureListener<?> l: listeners) {
if (l == null) {
break;
}
notifyProgressiveListener0(future, l, progress, total);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void notifyProgressiveListener0(
ProgressiveFuture future, GenericProgressiveFutureListener l, long progress, long total) {
try {
l.operationProgressed(future, progress, total);
} catch (Throwable t) {
logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationProgressed()", t);
}
}
private static boolean isCancelled0(Object result) {
return result instanceof CauseHolder && ((CauseHolder) result).cause instanceof CancellationException;
}
private static boolean isDone0(Object result) {
return result != null && result != UNCANCELLABLE;
}
private static final class CauseHolder {
final Throwable cause;
CauseHolder(Throwable cause) {
this.cause = cause;
}
}
private static void safeExecute(EventExecutor executor, Runnable task) {
try {
executor.execute(task);
} catch (Throwable t) {
rejectedExecutionLogger.error("Failed to submit a listener notification task. Event loop shut down?", t);
}
}
}