コレクションのスレッドセキュリティ

2622 ワード

スレッドセキュリティの集合:Vector,HashTableスレッドがセキュリティでない集合:ArrayList,LinkedList,HashSet,TreeSet,HashMap,TreeMap
スレッドが安全でない集合はどのようにスレッドの安全を保証しますか?Collectionsツールクラスの同期メソッドSynchronizedList()、SynchronizedSet()、SynchronizedMap()を使用すると、List、Set、Mapのセットがスレッドの安全なセットになることが保証されます.スレッドセキュリティセットのメソッドはsynchronizedによって修飾され、スレッドセキュリティが保証され、同期メソッドによってスレッドセキュリティのセットになることは、セットの元のメソッドにsynchronizedブロックを加えてスレッドセキュリティを保証する.
使用法:static List synchronizedList(List list)static Set synchronizedSet(Set)static Map synchronizedMap(Map map)
例:
List list = new List();
List synList = list.SynchronizedList(list);

スレッドセキュリティセットは必ずスレッドセキュリティになりますか?いいえ
スレッドセキュリティの集合も同期メソッドが保証するスレッドセキュリティの集合も,集合中のメソッドに同期ロックを付加し,同期ロックを付加した適合演算ではスレッドセキュリティを保証できないか,手動で同期ロックを付加する必要がある.
例:
public void run() {
    for (int i = 0; i < 5; i++) {
        if (synList.size() < 3) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synList.add(i);
            System.out.println(i);
        }
    }
}

前例のsynList.size()とsynList.add()は同期されていますが、複合操作ではスレッドのセキュリティを保証することはできません.if文ブロックの前後にsynchronized同期ロックを追加する必要があります.結果:0 0 1
反復の同期についての質問:1)反復プロセス中に集合長の変化があってはならないこと、すなわちadd()とremove()操作があってはならないこと、そうでないとC o n c u r r e ntModificationException異常が発生することが分かった.一方、1つのコレクション反復中に、他のスレッドがコレクション内の要素を変更すると、反復の効果に影響します.マルチスレッド中の1つのセットの反復を防止するために、他のスレッドはadd()、remove()、set()を実行し、マルチスレッド内のスレッドの安全なセットの反復器はsynchronized同期ロックを追加する必要があります.反復器およびwhileループの取得は、同期ロック内に配置され、同期ロックのロックオブジェクトはadd()、remove()、set()同期ロックと同じオブジェクトでなければなりません.ソースコードの表示、すなわち同期後の集合オブジェクトです.
例:
//Must Object on which to synchronize.
synchronized (synList) {
    //Must be in synchronized block
    Iterator it = synList.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}

2)強化forループループは反復器と同様であり,マルチスレッドでもC o n c u r r r e ntModificationException異常が発生する.
例:
synchronized (synList) {
    for(Integer i : synList){
        System.out.println(it.next());
    }
}

3)第3の遍歴方式もあり,通常forサイクル遍歴では異常は起こらない.ループ中に他のスレッドがセット要素を変更すると、ループに影響します.
例:
synchronized (synList) {
    for(int i = 0; i < synList.size(); i++){
        System.out.println(synList.get(i));
    }
}

4)listIterator遍歴器は集合の遍歴と同時に集合の長さを変更することも可能であるため,C o n c u r r e n tModificationException異常は発生せず,同期ロックを必要とせず,listIteratorに従来の方法add()とremove()は遍歴と同時に要素の追加と削除の操作を実現できる.