ブラシインタビューの質問10:スレッドの安全性を確保するためにどのようにConcurrentHashMapの?

image.png




コレクションと同期をパッケージコレクションフレームワークハッシュテーブル、スタック、並行性の高いシナリオで非常に非効率的である、Javaが契約を提供し、並行性の高いシナリオに対処します。


私は、今日の問題は、私は面接の準備、李富春でしたか?

コンカレント・コンテナーを提供するJava?どのようにConcurrentHashMapの保証スレッドセーフ?

システムコンカレント・コンテナーのJava



Java同期コンテナシステムは、以下を有する:

1、ハッシュテーブル、スタック同期容器、内部同期キーワードsychronized確保する;

2、Collections.synchronizedMap同期ラッパー()、内部キーがsychronized同期を保証するために使用すること。

図3に示すように、容器は、同期と契約、そのようなConcurrentHashMapの、CopyOnWriteArrayListと、ArrayBlockingQueue、SynchronizedQueueを提供します

ConcurrentHashMapのの同時分析



なぜConcurrenHashMapありますか?

1は、高い並行性のシナリオの下でハッシュテーブルパフォーマンスの低下;

2、HashMapのはスレッドセーフされていない容器;

3、同期方法の使用が急速に高い同時実行シナリオの下での性能には適していない静止部分の性能を改善したが、が同期ラッパー需要;



答えに次の質問、どのようにConcurrentHashMapの保証スレッドセーフ?

java7


別ロック(セグメント)を使用してjava7バージョンはセキュリティ・スレッドを確保するために、実際に再進入ロック(RetrantLock)である
セグメントの数はconcurrentLevel決定され、デフォルト値は16であり、


膨張の膨張は、単一セグメントのための時間であり、書き込み動作また、ロック部分は、それがより効率的であるときに、データを修正する。

しかし、正確ではないかもしれない大きさの後に行きます。

下に示すようなデータ構造:

image.png

java8


java8セグメントが残るが、唯一のシーケンスの互換性を確保するために、構造上の機能を作用しません。

;内部には、揮発性データストレージの可視性を保証するために

、内部ロックが実際にsyncronized使用されている、特定のシーンでのCASの操作、ロックフリー同時動作を

jdk8で、syncronizedパフォーマンスが最適化されているため、比較再突入ロックは、メモリ消費量を削減することができます。

コードを参照してください。


final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException();
    int hash = spread(key.hashCode());
    int binCount = 0;
    for (Node<K,V>[] tab = table;;) {
        Node<K,V> f; int n, i, fh; K fk; V fv;
        if (tab == null || (n = tab.length) == 0)
            tab = initTable();
        else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
            // 利用CAS去进行无锁线程安全操作,如果bin是空的
            if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value)))
                break; 
        }
        else if ((fh = f.hash) == MOVED)
            tab = helpTransfer(tab, f);
        else if (onlyIfAbsent // 不加锁,进行检查
                 && fh == hash
                 && ((fk = f.key) == key || (fk != null && key.equals(fk)))
                 && (fv = f.val) != null)
            return fv;
        else {
            V oldVal = null;
            synchronized (f) {
                   // 细粒度的同步修改操作... 
                }
            }
            // Bin超过阈值,进行树化
            if (binCount != 0) {
                if (binCount >= TREEIFY_THRESHOLD)
                    treeifyBin(tab, i);
                if (oldVal != null)
                    return oldVal;
                break;
            }
        }
    }
    addCount(1L, binCount);
    return null;
}

概要


このセクションでは、java7で提供分類javaの同時コンテナに応答し、ConcurrentHashMapの、java8はスレッドセーフを確保する方法です。

私はクリアするためのデータ構造で絵画、インタビュアー別々のロックをお願いしたいです。

image.png

元は容易ではない、私たちの相補性と共通の進歩させ、ソースを明記してください、マルチ通信を歓迎

公開された110元の記事 ウォン称賛10 ビュー20000 +

おすすめ

転載: blog.csdn.net/tian583391571/article/details/105100258