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();
    }
}

 

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