當前位置:
首頁 > 知識 > Netty 從入門到精通(二)

Netty 從入門到精通(二)

上節講到:Netty 從入門到精通(一)


這節我們繼續分析 丟棄伺服器

public static void main(String[] args) throws Exception {
int port = 8089;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
}
new DiscardServer(port).run();
}

Netty 從入門到精通(二)

打開今日頭條,查看更多圖片

首先分析這段代碼,這段代碼非常見,設置了埠,啟動伺服器,那麼我來看下,這個run到底做了一些什麼?

EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
EventLoopGroup workerGroup = new NioEventLoopGroup();

首先,映入眼帘的是EventLoopGroup,顧名思義,事件循環組,我們開始創建了兩個事件循環組,那麼現在我們開始一起閱讀,這個事件循環組到底是什麼?

public class NioEventLoopGroup extends MultithreadEventLoopGroup

NIO事件循環組,繼承自混合線程事件循環組,咱們先不考慮這個父類,就先對這個NioEventLoopGroup一探究竟


NioEventLoopGroup

public NioEventLoopGroup() {
this(0);
}

自身構造函數調用

public NioEventLoopGroup(int nThreads) {
this(nThreads, (Executor)null);
}

繼續自身構造函數調用

Netty 從入門到精通(二)

public NioEventLoopGroup(int nThreads, Executor executor) {
this(nThreads, executor, SelectorProvider.provider());
}

此時我們要牢記 execute是null

public NioEventLoopGroup(int nThreads, Executor executor) {
this(nThreads, executor, SelectorProvider.provider());
}

public NioEventLoopGroup(int nThreads, Executor executor, SelectorProvider selectorProvider) {

this(nThreads, executor, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);

}

如果線程數量為0,那麼要使用DEFAULT_EVENT_LOOP_THREADS設置線程數量

也就是cpu核心數量2倍

private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

NettyRuntime.availableProcessors() 是cpu核心數量



protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {

super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);

}

protected MultithreadEventExecutorGroup(int nThreads, Executor executor, Object... args) {

this(nThreads, executor, DefaultEventExecutorChooserFactory.INSTANCE, args);


}

經過漫長的自身構造函數調用之後,我們終於看見了真的面目,看了下面這段,我們似乎並不難看太懂,但是我們可以繼續從主函數中,往下去看

protected MultithreadEventExecutorGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory, Object... args) {
this.terminatedChildren = new AtomicInteger();
this.terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
} else {
if (executor == null) {
executor = new ThreadPerTaskExecutor(this.newDefaultThreadFactory());
}
this.children = new EventExecutor[nThreads];
int j;
for(int i = 0; i < nThreads; ++i) {
boolean success = false;
boolean var18 = false;
try {
var18 = true;
this.children[i] = this.newChild((Executor)executor, args);
success = true;
var18 = false;
} catch (Exception var19) {
throw new IllegalStateException("failed to create a child event loop", var19);
} finally {
if (var18) {
if (!success) {
int j;
for(j = 0; j < i; ++j) {
this.children[j].shutdownGracefully();
}
for(j = 0; j < i; ++j) {
EventExecutor e = this.children[j];
try {
while(!e.isTerminated()) {
e.awaitTermination(2147483647L, TimeUnit.SECONDS);
}
} catch (InterruptedException var20) {
Thread.currentThread().interrupt();
break;
}
}
}
}
}
if (!success) {
for(j = 0; j < i; ++j) {
this.children[j].shutdownGracefully();
}
for(j = 0; j < i; ++j) {
EventExecutor e = this.children[j];
try {
while(!e.isTerminated()) {
e.awaitTermination(2147483647L, TimeUnit.SECONDS);
}
} catch (InterruptedException var22) {
Thread.currentThread().interrupt();
break;
}
}
}
}
this.chooser = chooserFactory.newChooser(this.children);
FutureListener<Object> terminationListener = new FutureListener<Object>() {
public void operationComplete(Future<Object> future) throws Exception {
if (MultithreadEventExecutorGroup.this.terminatedChildren.incrementAndGet() == MultithreadEventExecutorGroup.this.children.length) {
MultithreadEventExecutorGroup.this.terminationFuture.setSuccess((Object)null);
}
}
};
EventExecutor[] var24 = this.children;
j = var24.length;
for(int var26 = 0; var26 < j; ++var26) {
EventExecutor e = var24[var26];
e.terminationFuture().addListener(terminationListener);
}
Set<EventExecutor> childrenSet = new LinkedHashSet(this.children.length);
Collections.addAll(childrenSet, this.children);
this.readonlyChildren = Collections.unmodifiableSet(childrenSet);
}
}


ServerBootstrap

既然上面的看不懂,我們先看一下ServerBootstrap,這個類的構造函數還是非常簡單的

ServerBootstrap b = new ServerBootstrap(); // (2)

public ServerBootstrap() {
}

這樣我們創建了這個對象

下面看關鍵代碼 b.group(bossGroup, workerGroup)

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {

super.group(parentGroup);

if (childGroup == null) {

throw new NullPointerException("childGroup");

} else if (this.childGroup != null) {

throw new IllegalStateException("childGroup set already");

} else {

this.childGroup = childGroup;

return this;

}


}

可以看出,parentgroup交給父類設置,children交給子類進行設置,並且保證,這兩個傳入的對象不空,並且之前沒有被設置過。最後返回了對象本身,這樣可以進行鏈式設置。

然後繼續

.channel(NioServerSocketChannel.class) // (3)

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 青峰科技 的精彩文章:

Netty 從入門到精通(一)

TAG:青峰科技 |