Tomcat NIO模型之——LimitLatch连接限制器源码分析

直接上源码,注释分析:

package com.play.english.tomcat.thread;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @author chaiqx on 2020/5/25
 */
public class LimitLatch {

    private final Sync sync;//线程同步器
    private final AtomicLong count;//当前连接数目
    private volatile long limit;//最大限制连接数
    private volatile boolean released;//是否线程全部释放

    /**
     * 继承的AQS
     * AQS其实就是一个框架,具体需要我们去控制线程的阻塞和唤醒
     */
    private class Sync extends AbstractQueuedSynchronizer {

        public Sync() {

        }

        /**
         * 主要是判断是否达到最大限制数
         * <p>
         * 如果超过最大限制数的话返回-1 否则返回1
         * <p>
         * 其实最后主要用来AQS的线程是否阻塞判断
         *
         * @param args
         * @return
         */
        @Override
        protected int tryAcquireShared(int args) {
            long newCount = count.incrementAndGet(); //加入一个连接之后的连接数目
            if (!released && newCount > limit) {//不是所有线程唤醒并且已经大于最大限制数
                count.decrementAndGet();//把自己的该1个连接数目去掉
                return -1;//返回-1表示该线程将要进入阻塞
            } else {
                return 1;//返回1表示该线程直接通过不用阻塞
            }
        }

        /**
         * 主要是释放连接数
         *
         * @param args
         * @return
         */
        @Override
        protected boolean tryReleaseShared(int args) {
            count.decrementAndGet();//释放1个连接
            return true;
        }
    }

    /**
     * 构造函数
     * <p>
     * 初始化私有变量
     *
     * @param limit
     */
    public LimitLatch(long limit) {
        this.limit = limit;
        this.count = new AtomicLong(0);
        this.sync = new Sync();
    }

    /**
     * 调用这个用来进行线程的阻塞
     * <p>
     * 如果当前连接数已经满了,则线程进行循环阻塞
     *
     * @throws InterruptedException
     */
    public void countUpOrAwait() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    /**
     * 释放一个连接
     * <p>
     * 唤醒一个线程
     *
     * @return
     */
    public long countDown() {
        sync.releaseShared(0);
        return getCount();
    }

    /**
     * 唤醒所有的线程
     * <p>
     * 释放一个连接
     *
     * @return
     */
    public boolean releaseAll() {
        released = true;
        return sync.releaseShared(0);
    }

    /**
     * 重置连接限制器
     */
    public void reset() {
        this.count.set(0);
        released = false;
    }

    /**
     * 获取当前连接数目
     *
     * @return
     */
    public long getCount() {
        return count.get();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章