java.nio.channels.enhance.EnhanceAsynchronousChannelGroup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zodiac-sdk-nio Show documentation
Show all versions of zodiac-sdk-nio Show documentation
Zodiac SDK NIO2(New Non-Blocking IO)
package java.nio.channels.enhance;
import java.io.IOException;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
class EnhanceAsynchronousChannelGroup extends AsynchronousChannelGroup {
/**
* 写线程数。
*/
private static final String WRITE_THREAD_NUM = "java.nio.channels.asyncWriteThreads";
/**
* accept线程数,该线程数只可少于等于进程内启用的服务端个数,多出无效。
*/
private static final String ACCEPT_THREAD_NUM = "java.nio.channels.asyncAcceptThreads";
/**
* 递归回调次数上限。
*/
public static final int MAX_INVOKER = 8;
/**
* 读回调处理线程池,可用于业务处理。
*/
private final ExecutorService readExecutorService;
/**
* 写回调线程池。
*/
private final ExecutorService writeExecutorService;
/**
* write工作组。
*/
private final Worker[] writeWorkers;
/**
* read工作组。
*/
private final Worker[] readWorkers;
/**
* 线程池分配索引。
*/
private final AtomicInteger readIndex = new AtomicInteger(0);
private final AtomicInteger writeIndex = new AtomicInteger(0);
/**
* 定时任务线程池。
*/
private final ScheduledThreadPoolExecutor scheduledExecutor;
/**
* 服务端accept线程池。
*/
private final ExecutorService acceptExecutorService;
/**
* accept工作组。
*/
private final Worker[] acceptWorkers;
private Worker futureWorker;
/**
* 同步IO线程池。
*/
private ExecutorService futureExecutorService;
/**
* group运行状态。
*/
private boolean running = true;
protected EnhanceAsynchronousChannelGroup(AsynchronousChannelProvider provider, ExecutorService readExecutorService, int threadNum) throws IOException {
super(provider);
//init threadPool for read
this.readExecutorService = readExecutorService;
this.readWorkers = new Worker[threadNum];
for (int i = 0; i < threadNum; i++) {
readWorkers[i] = new Worker(selectionKey -> {
EnhanceAsynchronousSocketChannel asynchronousSocketChannel = (EnhanceAsynchronousSocketChannel) selectionKey.attachment();
asynchronousSocketChannel.doRead(true);
});
this.readExecutorService.execute(readWorkers[i]);
}
//init threadPool for write and connect
final int writeThreadNum = getIntSystemProperty(WRITE_THREAD_NUM, 1);
final int acceptThreadNum = getIntSystemProperty(ACCEPT_THREAD_NUM, 1);
writeExecutorService = getThreadPoolExecutor("smart-socket:write-", writeThreadNum);
this.writeWorkers = new Worker[writeThreadNum];
for (int i = 0; i < writeThreadNum; i++) {
writeWorkers[i] = new Worker(selectionKey -> {
EnhanceAsynchronousSocketChannel asynchronousSocketChannel = (EnhanceAsynchronousSocketChannel) selectionKey.attachment();
asynchronousSocketChannel.doWrite();
});
writeExecutorService.execute(writeWorkers[i]);
}
//init threadPool for accept
acceptExecutorService = getThreadPoolExecutor("smart-socket:connect-", acceptThreadNum);
acceptWorkers = new Worker[acceptThreadNum];
for (int i = 0; i < acceptThreadNum; i++) {
acceptWorkers[i] = new Worker(selectionKey -> {
if (selectionKey.isAcceptable()) {
EnhanceAsynchronousServerSocketChannel serverSocketChannel = (EnhanceAsynchronousServerSocketChannel) selectionKey.attachment();
serverSocketChannel.doAccept();
} else if (selectionKey.isConnectable()) {
EnhanceAsynchronousSocketChannel asynchronousSocketChannel = (EnhanceAsynchronousSocketChannel) selectionKey.attachment();
asynchronousSocketChannel.doConnect();
}
});
acceptExecutorService.execute(acceptWorkers[i]);
}
scheduledExecutor = new ScheduledThreadPoolExecutor(1, r -> new Thread(r, "smart-socket:scheduled"));
}
/**
* 同步IO注册异步线程,防止主IO线程阻塞。
*
* @param register 注册器
* @param opType 操作类型
* @throws IOException 异常
*/
public synchronized void registerFuture(Consumer register, int opType) throws IOException {
if (futureWorker == null) {
futureExecutorService = getThreadPoolExecutor("smart-socket:future-", 1);
futureWorker = new Worker(selectionKey -> {
EnhanceAsynchronousSocketChannel asynchronousSocketChannel = (EnhanceAsynchronousSocketChannel) selectionKey.attachment();
switch (opType) {
case SelectionKey.OP_READ:
removeOps(selectionKey, SelectionKey.OP_READ);
asynchronousSocketChannel.doRead(true);
break;
case SelectionKey.OP_WRITE:
removeOps(selectionKey, SelectionKey.OP_WRITE);
asynchronousSocketChannel.doWrite();
break;
default:
throw new UnsupportedOperationException("unSupport opType: " + opType);
}
});
futureExecutorService.execute(futureWorker);
}
futureWorker.addRegister(register);
}
private ThreadPoolExecutor getThreadPoolExecutor(final String prefix, int threadNum) {
return new ThreadPoolExecutor(threadNum, threadNum, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(), new ThreadFactory() {
private final AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, prefix + atomicInteger.getAndIncrement());
}
});
}
private int getIntSystemProperty(String key, int defaultValue) {
String value = System.getProperty(key);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return Integer.parseInt(value);
} catch (Exception e) {
e.printStackTrace();
}
return defaultValue;
}
/**
* 移除关注事件
*
* @param selectionKey 待操作的selectionKey
* @param opt 移除的事件
*/
public void removeOps(SelectionKey selectionKey, int opt) {
if (selectionKey.isValid() && (selectionKey.interestOps() & opt) != 0) {
selectionKey.interestOps(selectionKey.interestOps() & ~opt);
}
}
public Worker getReadWorker() {
return readWorkers[(readIndex.getAndIncrement() & Integer.MAX_VALUE) % readWorkers.length];
}
public Worker getWriteWorker() {
return writeWorkers[(writeIndex.getAndIncrement() & Integer.MAX_VALUE) % writeWorkers.length];
}
public Worker getAcceptWorker() {
return acceptWorkers[(writeIndex.getAndIncrement() & Integer.MAX_VALUE) % acceptWorkers.length];
}
public Worker getConnectWorker() {
return acceptWorkers[(writeIndex.getAndIncrement() & Integer.MAX_VALUE) % acceptWorkers.length];
}
public ScheduledThreadPoolExecutor getScheduledExecutor() {
return scheduledExecutor;
}
@Override
public boolean isShutdown() {
return readExecutorService.isShutdown();
}
@Override
public boolean isTerminated() {
return readExecutorService.isTerminated();
}
@Override
public void shutdown() {
running = false;
readExecutorService.shutdown();
writeExecutorService.shutdown();
if (acceptExecutorService != null) {
acceptExecutorService.shutdown();
}
if (futureExecutorService != null) {
futureExecutorService.shutdown();
}
scheduledExecutor.shutdown();
}
@Override
public void shutdownNow() {
running = false;
readExecutorService.shutdownNow();
writeExecutorService.shutdownNow();
if (acceptExecutorService != null) {
acceptExecutorService.shutdownNow();
}
if (futureExecutorService != null) {
futureExecutorService.shutdownNow();
}
scheduledExecutor.shutdownNow();
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return readExecutorService.awaitTermination(timeout, unit);
}
public void interestOps(Worker worker, SelectionKey selectionKey, int opt) {
if ((selectionKey.interestOps() & opt) != 0) {
return;
}
selectionKey.interestOps(selectionKey.interestOps() | opt);
//Worker线程无需wakeup
if (worker.getWorkerThread() != Thread.currentThread()) {
selectionKey.selector().wakeup();
}
}
class Worker implements Runnable {
/**
* 当前Worker绑定的Selector
*/
private final Selector selector;
/**
* 待注册的事件
*/
private final ConcurrentLinkedQueue> registers = new ConcurrentLinkedQueue<>();
private final Consumer consumer;
int invoker = 0;
int modCount;
private Thread workerThread;
Worker(Consumer consumer) throws IOException {
this.selector = Selector.open();
this.consumer = consumer;
}
/*
* 注册事件
*/
final void addRegister(Consumer register) {
registers.offer(register);
modCount++;
selector.wakeup();
}
public final Thread getWorkerThread() {
return workerThread;
}
@Override
public final void run() {
workerThread = Thread.currentThread();
// 优先获取SelectionKey,若无关注事件触发则阻塞在selector.select(),减少select被调用次数
Set keySet = selector.selectedKeys();
try {
int v = 0;
while (running) {
Consumer register;
if (v != modCount) {
v = modCount;
while ((register = registers.poll()) != null) {
register.accept(selector);
}
}
selector.select();
Iterator keyIterator = keySet.iterator();
// 执行本次已触发待处理的事件
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
invoker = 0;
keyIterator.remove();
consumer.accept(key);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
selector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}