国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java并發(fā)實戰(zhàn):連接池實現(xiàn)

XboxYan / 837人閱讀

摘要:池化技術(shù)簡介在我們使用數(shù)據(jù)庫的過程中,我們往往使用數(shù)據(jù)庫連接池而不是直接使用數(shù)據(jù)庫連接進行操作,這是因為每一個數(shù)據(jù)庫連接的創(chuàng)建和銷毀的代價是昂貴的,而池化技術(shù)則預(yù)先創(chuàng)建了資源,這些資源是可復用的這樣就保證了在多用戶情況下只能使用指定數(shù)目的資

池化技術(shù)簡介

在我們使用數(shù)據(jù)庫的過程中,我們往往使用數(shù)據(jù)庫連接池而不是直接使用數(shù)據(jù)庫連接進行操作,這是因為每一個數(shù)據(jù)庫連接的創(chuàng)建和銷毀的代價是昂貴的,而池化技術(shù)則預(yù)先創(chuàng)建了資源,這些資源是可復用的,這樣就保證了在多用戶情況下只能使用指定數(shù)目的資源,避免了一個用戶創(chuàng)建一個連接資源,造成程序運行開銷過大。

連接池實現(xiàn)原理

這里只實現(xiàn)一個簡易的連接池,更多復雜的需求可根據(jù)該連接池進行改進,該連接池主要參數(shù)如下:

一個繁忙隊列busy

一個空閑隊列idle

連接池最大活動連接數(shù)maxActive

連接池最大等待時間maxWait

連接池的活動連接數(shù)activeSize

程序流程圖如下:

代碼實現(xiàn)

泛型接口ConnectionPool.java

public interface ConnectionPool {

    /**
     * 初始化池資源
     * @param maxActive 池中最大活動連接數(shù)
     * @param maxWait 最大等待時間
     */
    void init(Integer maxActive, Long maxWait);

    /**
     * 從池中獲取資源
     * @return 連接資源
     */
    T getResource() throws Exception;

    /**
     * 釋放連接
     * @param connection 正在使用的連接
     */
    void release(T connection) throws Exception;

    /**
     * 釋放連接池資源
     */
    void close();


}

以zookeeper為例,實現(xiàn)zookeeper連接池,ZookeeperConnectionPool.java

public class ZookeeperConnectionPool implements ConnectionPool {
    //最大活動連接數(shù)
    private Integer maxActive; 
    //最大等待時間
    private Long maxWait; 
    //空閑隊列
    private LinkedBlockingQueue idle = new LinkedBlockingQueue<>();
    //繁忙隊列
    private LinkedBlockingQueue busy = new LinkedBlockingQueue<>();
    //連接池活動連接數(shù)
    private AtomicInteger activeSize = new AtomicInteger(0);
    //連接池關(guān)閉標記
    private AtomicBoolean isClosed = new AtomicBoolean(false);
    //總共獲取的連接記數(shù)
    private AtomicInteger createCount = new AtomicInteger(0);
    //等待zookeeper客戶端創(chuàng)建完成的計數(shù)器
    private static ThreadLocal latchThreadLocal = ThreadLocal.withInitial(() -> new CountDownLatch(1));

    public ZookeeperConnectionPool(Integer maxActive, Long maxWait) {
        this.init(maxActive, maxWait);
    }

    @Override
    public void init(Integer maxActive, Long maxWait) {
        this.maxActive = maxActive;
        this.maxWait = maxWait;
    }

    @Override
    public ZooKeeper getResource() throws Exception {
        ZooKeeper zooKeeper;
        Long nowTime = System.currentTimeMillis();
        final CountDownLatch countDownLatch = latchThreadLocal.get();
        
        //空閑隊列idle是否有連接
        if ((zooKeeper = idle.poll()) == null) {
            //判斷池中連接數(shù)是否小于maxActive
            if (activeSize.get() < maxActive) {
                //先增加池中連接數(shù)后判斷是否小于等于maxActive
                if (activeSize.incrementAndGet() <= maxActive) {
                    //創(chuàng)建zookeeper連接
                    zooKeeper = new ZooKeeper("localhost", 5000, (watch) -> {
                        if (watch.getState() == Watcher.Event.KeeperState.SyncConnected) {
                            countDownLatch.countDown();
                        }
                    });
                    countDownLatch.await();
                    System.out.println("Thread:" + Thread.currentThread().getId() + "獲取連接:" + createCount.incrementAndGet() + "條");
                    busy.offer(zooKeeper);
                    return zooKeeper;
                } else {
                    //如增加后發(fā)現(xiàn)大于maxActive則減去增加的
                    activeSize.decrementAndGet();
                }
            }
            //若活動線程已滿則等待busy隊列釋放連接
            try {
                System.out.println("Thread:" + Thread.currentThread().getId() + "等待獲取空閑資源");
                Long waitTime = maxWait - (System.currentTimeMillis() - nowTime);
                zooKeeper = idle.poll(waitTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                throw new Exception("等待異常");
            }
            //判斷是否超時
            if (zooKeeper != null) {
                System.out.println("Thread:" + Thread.currentThread().getId() + "獲取連接:" + createCount.incrementAndGet() + "條");
                busy.offer(zooKeeper);
                return zooKeeper;
            } else {
                System.out.println("Thread:" + Thread.currentThread().getId() + "獲取連接超時,請重試!");
                throw new Exception("Thread:" + Thread.currentThread().getId() + "獲取連接超時,請重試!");
            }
        }
        //空閑隊列有連接,直接返回
        busy.offer(zooKeeper);
        return zooKeeper;
    }

    @Override
    public void release(ZooKeeper connection) throws Exception {
        if (connection == null) {
            System.out.println("connection 為空");
            return;
        }
        if (busy.remove(connection)){
            idle.offer(connection);
        } else {
            activeSize.decrementAndGet();
            throw new Exception("釋放失敗");
        }
    }

    @Override
    public void close() {
        if (isClosed.compareAndSet(false, true)) {
            idle.forEach((zooKeeper) -> {
                try {
                    zooKeeper.close();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            busy.forEach((zooKeeper) -> {
                try {
                    zooKeeper.close();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}
測試用例

這里創(chuàng)建20個線程并發(fā)測試連接池,Test.java

public class Test {

    public static void main(String[] args) throws Exception {
        int threadCount = 20;
        Integer maxActive = 10;
        Long maxWait = 10000L;
        ZookeeperConnectionPool pool = new ZookeeperConnectionPool(maxActive, maxWait);
        CountDownLatch countDownLatch = new CountDownLatch(20);
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                countDownLatch.countDown();
                try {
                    countDownLatch.await();
                    ZooKeeper zooKeeper = pool.getResource();
                    Thread.sleep(2000);
                    pool.release(zooKeeper);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }).start();
        }
        while (true){

        }
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73054.html

相關(guān)文章

  • 阿里 2021 版最全 Java 并發(fā)編程筆記,看完我才懂了“內(nèi)卷”的真正意義

    摘要:純分享直接上干貨操作系統(tǒng)并發(fā)支持進程管理內(nèi)存管理文件系統(tǒng)系統(tǒng)進程間通信網(wǎng)絡(luò)通信阻塞隊列數(shù)組有界隊列鏈表無界隊列優(yōu)先級有限無界隊列延時無界隊列同步隊列隊列內(nèi)存模型線程通信機制內(nèi)存共享消息傳遞內(nèi)存模型順序一致性指令重排序原則內(nèi)存語義線程 純分享 , 直接上干貨! 操作系統(tǒng)并發(fā)支持 進程管理內(nèi)存管...

    不知名網(wǎng)友 評論0 收藏0
  • Java深入-框架技巧

    摘要:從使用到原理學習線程池關(guān)于線程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實現(xiàn)在軟件開發(fā)中,分散于應(yīng)用中多出的功能被稱為橫切關(guān)注點如事務(wù)安全緩存等。 Java 程序媛手把手教你設(shè)計模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經(jīng)風雨慢慢變老,回首走過的點點滴滴,依然清楚的記得當初愛情萌芽的模樣…… Java 進階面試問題列表 -...

    chengtao1633 評論0 收藏0
  • Java多線程編程實戰(zhàn):模擬大量數(shù)據(jù)同步

    摘要:所以得出結(jié)論需要分配較多的線程進行讀數(shù)據(jù),較少的線程進行寫數(shù)據(jù)。注意多線程編程對實際環(huán)境和需求有很大的依賴,需要根據(jù)實際的需求情況對各個參數(shù)做調(diào)整。 背景 最近對于 Java 多線程做了一段時間的學習,筆者一直認為,學習東西就是要應(yīng)用到實際的業(yè)務(wù)需求中的。否則要么無法深入理解,要么硬生生地套用技術(shù)只是達到炫技的效果。 不過筆者仍舊認為自己對于多線程掌握不夠熟練,不敢輕易應(yīng)用到生產(chǎn)代碼中...

    elliott_hu 評論0 收藏0

發(fā)表評論

0條評論

XboxYan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<