中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中并發容器J.U.C怎么用

發布時間:2021-10-19 15:52:31 來源:億速云 閱讀:121 作者:柒染 欄目:大數據

這篇文章將為大家詳細講解有關java中并發容器J.U.C怎么用,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

并發容器是JDK提供的一個包名:java.util.concurrent

ArrayList -> CopyOnWriteArrayList

CopyOnWriteArrayList是線程安全的,寫操作時復制,當有新元素添加到CopyOnWriteArrayList時先從原有的list中拷貝出來,然后在新的list上寫操作,寫完之后將原來的list指向新的list,整個操作都是在鎖的保護下進行的,這樣做為了防止多線程下多個add操作時產生多個副本,導致最終的數據不是我們期望的。

CopyOnWriteArrayList有幾個缺點:

  1. 由于寫操作時需要拷貝數組,因此比較消耗內存。當元素內容比較多時會導致Full GC

  2. 不能用于實時讀的場景,拷貝數組需要時間,所以調用一個set操作后,讀取到的數據還可能是舊的,雖然能做到最終一致性,但是無法滿足實時性要求。因此CopyOnWriteArrayList更適合讀多寫少的場景。如果不清楚add或者set多少次操作,這個CopyOnWriteArrayList最好慎用。

HashSet、TreeSet->CopyOnWriteArraySet、ConcurrentSkipListSet

CopyOnWriteArraySet同樣也是線程安全的,底層實現是CopyOnWriteArrayList,因此CopyOnWriteArraySet適合大小比較小的set集合只讀操作大于寫操作,因為需要復制基礎數組,所以對于可變的操作(add set)的開銷大。使用迭代器的迭代速度很快,而且不會有線程安全問題。

ConcurrentSkipListSet與TreeSet用一樣,是支持自然排序的,可以在構造時自定義比較器。在多線程情況下ConcurrentSkipListSet里面的contains()、add()、remove()是線程安全的,多個線程可以并發的執行插入移除和訪問操作,但是對于批量操作例如addAll(),removeAll(),retainAll()、containsAll()并不能保證以原子方式執行,這些操作可以被其他線程打斷,需要額外增加鎖才行,因為他們實現方式是分別調用contains()、add()、remove()的。因為并發容器只能保證每一次的contains()、add()、remove()操作時原子性的,而不能保證每一次批量操作都不會被其他線程打斷。也就是多個add,多個remove操作時有其他線程進來。

HashMap、TreeMap -> ConcurrentHashMap、ConcurrentSkipListMap

ConcurrentHashMap不允許null,在實際的應用中除了少數的插入操作和刪除操作外,絕大部分我們使用map都是使用讀取操作,而且讀操作大多數都是成功的,基于這個前提,ConcurrentHashMap針對讀操作做了大量的優化,因此這個類具有很高的并發性,高并發場景下有很好的表現。

ConcurrentSkipListMap是TreeMap的線程安全版本。內部是使用skipList跳表的結構實現的。ConcurrentHashMap的存取速度是ConcurrentSkipListMap的4倍左右,但是ConcurrentSkipListMap的key是有序的而ConcurrentHashMap是做不到的,ConcurrentSkipListMap支持更高的并發,ConcurrentSkipListMap的存取時間是與線程數無關的,在數據量一定的情況下并發線程數越多ConcurrentSkipListMap越能體現出優勢。

在較低并發情況下,可以使用Collections.synchronizedSortedMap()來實現,也可以提供較好的效率。在高并發的情況下可以使用ConcurrentSkipListMap提供更高的并發度。要對鍵值對進行排序時可以使用ConcurrentSkipListMap。

@Slf4j
@ThreadSafe
public class ConcurrentHashMapExample {
    // 請求總數
    public static int clientTotal = 5000;

    // 同時并發執行的線程數
    public static int threadTotal = 200;

    private static Map<Integer, Integer> map = new ConcurrentHashMap<>();

    public static void main(String[] args) throws InterruptedException {
        //線程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        //定義信號量
        final Semaphore semaphore = new Semaphore(threadTotal);
        //定義計數器
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for(int i = 0; i < clientTotal; i++) {
            final int count  = i;
            executorService.execute(() ->{
                try {
                    semaphore.acquire();
                    update(count);
                    semaphore.release();
                } catch (InterruptedException e) {

                    log.error("exception", e);
                }
                countDownLatch.countDown();

            });
        }
        countDownLatch.await();
        executorService.shutdown();
        log.info("size:{}",map.size()) ;
    }

    public static void update(int i) {
        map.put(i,i);
    }

}

輸出結果正確。

 concurrentSkipListMap:

private static Map<Integer, Integer> map = new ConcurrentSkipListMap<>();

J.U.C

java中并發容器J.U.C怎么用

安全共享對象策略 - 總結

  • 線程限制:一個被線程限制的對象,由線程獨占,并且只能被占有它的線程修改。

  • 共享只讀:一個共享只讀的對象,在沒有額外同步的情況下,可以被多個線程并發訪問,但是任何線程都不能修改它。

  • 線程安全對象:一個線程安全的對象或者容器,在內部通過同步機制來保證線程安全,所以其他線程無需額外的同步就可以通過公共接口隨意訪問它。

  • 被守護對象:被守護對象只能通過獲取特定的鎖來訪問。

關于java中并發容器J.U.C怎么用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

驻马店市| 剑川县| 海原县| 固阳县| 泰安市| 将乐县| 凌云县| 富阳市| 浙江省| 玉门市| 建瓯市| 札达县| 江源县| 濮阳市| 满城县| 定远县| 镇坪县| 商都县| 县级市| 苍梧县| 阿鲁科尔沁旗| 东阳市| 桂平市| 新宾| 白城市| 福安市| 山东省| 巩义市| 广河县| 郧西县| 六安市| 大同县| 永胜县| 平果县| 珲春市| 大连市| 桂平市| 辽宁省| 湘潭市| 峨山| 桐城市|