線程特性使用集錦(threadLocal、併發容器(關於消費者生產者思考)、停止線程最佳實踐)

一:ThreadLocal<T> local = new ThreadLocal<>();

     如:

   ThreadLocal<Long> startTime = new ThreadLocal<>();

       使用:

     startTime.set(System.currentTimeMillis());  
     System.currentTimeMillis() - startTime.get(); 還有remove()方法。

 解析:使用 threadLocal 設置變量,此時該變量僅僅會在當前線程中進行保存刪除操作,不會影響到其他線程

二:併發集合容器使用之:CopyOnWriteArrayList();

       實現:

   this.hmilyParticipants = Lists.newCopyOnWriteArrayList();

     認識:CopyOnWriteArrayList 是一個安全的併發 arrayList集合,特性:讀時無鎖,寫時有鎖,適用於讀操作遠遠大於寫操作的情形。是一種讀寫分離的併發策略。底層原理:首先將當前容器複製一份,然後在新副本上執行寫操作,結束之後再將原容器的引用指向新容器。

     缺點:1.首先佔用內存大,每次都要生成一份新的副本,數據量大時,對內存影響較大。2、無法保證實時性,在寫操作過程中,不會阻塞但是讀取到的是老容器的數據。3、大量寫操作時性能極差。

三:如何安全停止一個線程

public class BestPractice extends Thread {
    private volatile boolean finished = false;   // ① volatile條件變量
    public void stopMe() {
        finished = true;    // ② 發出停止信號
    }
    @Override
    public void run() {
        while (!finished) {    // ③ 檢測條件變量
            // do dirty work   // ④業務代碼
        }
    }
}

使用信號量停止線程是最好的辦法,其次就是Thread.currentThread().interrupt();然後判斷 Thread.currentThread.isInterrupted()進行判斷 如:while(!Thread.currentThread.isInterrupted()){ break; }

四:爲什麼用BlockingQueue實現生產者消費者:

       首先併發集合容器包括:ConcurrentLinkedQueue(高性能的併發隊列,使用無鎖實現,基於樂觀鎖)、CopyOnWriteArrayList(讀寫分離的鎖策略) 以及 BlockingQueue(包括 ArrayBlockingQueue、LinkedBlockingQueue),在實踐中一直是使用阻塞隊列 BlockingQueue實現生產者消費者,究其原因就在於 BlockingQueue隊列中 的存放put()以及獲取 take()都是阻塞的,如:包含 notEmpty 和 notFull 兩把鎖,如果符合條件就會讓對應的鎖進行 等待 如: notEmpty.awit() 如果察覺到條件變化就調用 notEmpty.notify() 喚醒,這樣就不需要通過定時任務定時去判斷、刷新數據,因此使用 blockingQueue作爲生產者消費者。而因爲是加鎖的,所以性能不是很好,這時候 disruptor 這個無鎖的生產者消費者框架有了用武之地。

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