All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java.nio.channels.enhance.EnhanceAsynchronousChannelGroup Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
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();
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy