1、HiKariCP线程池 https://segmentfault.com/a/1190000019779684
FastList:关闭连接逆序关闭ResultSet、Statement、Connection;remove逆序,去除数据越界检查由业务保证
/** * This remove method is most efficient when the element being removed * is the last element. Equality is identity based, not equals() based. * Only the first matching element is removed. * * @param element the element to remove */ @Override public boolean remove(Object element) { for (int index = size - 1; index >= 0; index--) { if (element == elementData[index]) { final int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(elementData, index + 1, elementData, index, numMoved); } elementData[--size] = null; return true; } } return false; }
ConcurrentBag:使用threadlocal避免部分并发问题,获取连接先本地存储,无则共享队列CopyOnWriteArrayList,再无则等待;
/** * The method will borrow a BagEntry from the bag, blocking for the * specified timeout if none are available. * * @param timeout how long to wait before giving up, in units of unit * @param timeUnit a <code>TimeUnit</code> determining how to interpret the timeout parameter * @return a borrowed instance from the bag or null if a timeout occurs * @throws InterruptedException if interrupted while waiting */ public T borrow(long timeout, final TimeUnit timeUnit) throws InterruptedException { // Try the thread-local list first final List<Object> list = threadList.get(); for (int i = list.size() - 1; i >= 0; i--) { final Object entry = list.remove(i); @SuppressWarnings("unchecked") final T bagEntry = weakThreadLocals ? ((WeakReference<T>) entry).get() : (T) entry; if (bagEntry != null && bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) { return bagEntry; } } // Otherwise, scan the shared list ... then poll the handoff queue final int waiting = waiters.incrementAndGet(); try { for (T bagEntry : sharedList) { if (bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) { // If we may have stolen another waiter's connection, request another bag add. if (waiting > 1) { listener.addBagItem(waiting - 1); } return bagEntry; } } listener.addBagItem(waiting); timeout = timeUnit.toNanos(timeout); do { final long start = currentTime(); final T bagEntry = handoffQueue.poll(timeout, NANOSECONDS); if (bagEntry == null || bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) { return bagEntry; } timeout -= elapsedNanos(start); } while (timeout > 10_000); return null; } finally { waiters.decrementAndGet(); } } /** * This method will return a borrowed object to the bag. Objects * that are borrowed from the bag but never "requited" will result * in a memory leak. * * @param bagEntry the value to return to the bag * @throws NullPointerException if value is null * @throws IllegalStateException if the bagEntry was not borrowed from the bag */ public void requite(final T bagEntry) { bagEntry.setState(STATE_NOT_IN_USE); for (int i = 0; waiters.get() > 0; i++) { if (bagEntry.getState() != STATE_NOT_IN_USE || handoffQueue.offer(bagEntry)) { return; } else if ((i & 0xff) == 0xff) { parkNanos(MICROSECONDS.toNanos(10)); } else { yield(); } } final List<Object> threadLocalList = threadList.get(); if (threadLocalList.size() < 50) { threadLocalList.add(weakThreadLocals ? new WeakReference<>(bagEntry) : bagEntry); } }