| 15 | import org.jetbrains.annotations.NotNull; |
| 16 | |
| 17 | public class Selector extends Thread implements ByteBufferAllocator { |
| 18 | private static final @NotNull Logger logger = LogManager.getLogger(Selector.class); |
| 19 | |
| 20 | // 以下常量为临时兼容,以后会去掉,应该改用Selectors里的 |
| 21 | public static final int DEFAULT_BUFFER_SIZE = 32 * 1024; // 单个buffer的字节容量 |
| 22 | public static final int DEFAULT_BBPOOL_LOCAL_CAPACITY = 1000; // 本地池的最大保留buffer数量 |
| 23 | public static final int DEFAULT_BBPOOL_MOVE_COUNT = 1000; // 本地池和全局池之间移动一次的buffer数量 |
| 24 | public static final int DEFAULT_BBPOOL_GLOBAL_CAPACITY = 100 * DEFAULT_BBPOOL_MOVE_COUNT; // 全局池的最大buffer数量 |
| 25 | public static final int DEFAULT_SELECT_TIMEOUT = 0; // 0表示无超时,>0表示每次select的超时毫秒数 |
| 26 | |
| 27 | private final @NotNull Selectors selectors; |
| 28 | private final @NotNull java.nio.channels.Selector selector; |
| 29 | private final @NotNull ByteBuffer readBuffer; // 此线程共享的buffer,只能临时使用 |
| 30 | private final AtomicInteger wakeupNotified = new AtomicInteger(); |
| 31 | private final ArrayList<ByteBuffer> bbPool = new ArrayList<>(); // 当前selector的本地池,不会并发 |
| 32 | private final ConcurrentLinkedQueue<Runnable> taskQueue = new ConcurrentLinkedQueue<>(); |
| 33 | private long selectCount; |
| 34 | private boolean firstAction; |
| 35 | private volatile boolean running = true; |
| 36 | |
| 37 | // public final AtomicLong wakeupCount0 = new AtomicLong(); |
| 38 | // public final AtomicLong wakeupCount1 = new AtomicLong(); |
| 39 | // public final AtomicLong wakeupTime = new AtomicLong(); |
| 40 | // public long lastTime; |
| 41 | |
| 42 | public Selector(@NotNull Selectors selectors, @NotNull String threadName) throws IOException { |
| 43 | super(threadName); |
| 44 | setDaemon(true); |
| 45 | this.selectors = selectors; |
| 46 | selector = java.nio.channels.Selector.open(); |
| 47 | readBuffer = ByteBuffer.allocate(selectors.getReadBufferSize()); |
| 48 | } |
| 49 | |
| 50 | public @NotNull Selectors getSelectors() { |
| 51 | return selectors; |
| 52 | } |
| 53 | |
| 54 | @NotNull ByteBuffer getReadBuffer() { |
| 55 | return readBuffer; |
| 56 | } |
| 57 | |
| 58 | public long getSelectCount() { |
| 59 | return selectCount; |
| 60 | } |
| 61 | |
| 62 | public void addTask(@NotNull Runnable task) { |
| 63 | taskQueue.offer(task); |
| 64 | } |
| 65 | |
| 66 | @Override |
| 67 | public @NotNull ByteBuffer alloc() { |
| 68 | int n = bbPool.size(); |
| 69 | if (n <= 0) { |
| 70 | var bbPoolGlobalCapacity = selectors.getBbPoolGlobalCapacity(); |
| 71 | if (bbPoolGlobalCapacity > 0) { |
| 72 | var bbGlobalPool = selectors.getBbGlobalPool(); |
| 73 | int bbPoolMoveCount = selectors.getBbPoolMoveCount(); |
| 74 | var bbGlobalPoolLock = selectors.getBbGlobalPoolLock(); |
nothing calls this directly
no outgoing calls
no test coverage detected