JUCのセキュリティクラスコレクションを一覧表示します

安全でないコレクション

シングルスレッドアプリケーションでは、通常、new ArrayList()繰り返し可能なデータを格納するためのリストコレクションを指定するために採用されます。

ただし、マルチスレッドでは、予期しない問題が頻繁に発生します。コードは次のとおりです。

import java.util.*;
public class ListTest {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 创建list集合
        //List<String> lists = Arrays.asList("1", "2", "3");
        // 不安全
        List<String> lists = new ArrayList<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
    
    
            new Thread(()->{
    
    
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

その操作の結果は次のとおりです。
ここに画像の説明を挿入
同じオブジェクト情報のセットのマルチスレッド操作java.util.ConcurrentModificationException多くの場合、異常なエラーメッセージが表示されます。

Javaで提供されるセキュリティ対策

Java言語では、新しいリストコレクションとjava.util.Vectorクラスが提供されます。詳細については、次のコードを参照してください。

import java.util.*;
public class ListTest {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 创建list集合
        //List<String> lists = Arrays.asList("1", "2", "3");
        // 不安全
        //List<String> lists = new ArrayList<>();
		List<String> lists = new Vector<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
    
    
            new Thread(()->{
    
    
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

実行中のログは次のとおりです。エラーメッセージ
ここに画像の説明を挿入
は表示されませんjava.util.ConcurrentModificationException

データの安全な運用が保証されるのはなぜですか?
ここに画像の説明を挿入

撮影synchronized方法の発信者ロックの実装のため、追加操作の安全性を確保するために、マルチスレッド!

JUCの下でのセーフリストコレクション

JUCパッケージでは、安全なコレクションを作成する方法がいくつかあります。

  • 方法一:Collections.synchronizedList(new ArrayList <>());
import java.util.*;
public class ListTest {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
		List<String> lists = Collections.synchronizedList(new ArrayList<>());

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
    
    
            new Thread(()->{
    
    
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

基盤となるソースコード実装ロジックを表示する
ここに画像の説明を挿入

着信リストコレクションのタイプを判別し、タイプがそうであるかどうかを判別しjava.util.RandomAccess、そうである場合はjava.util.Collections.SynchronizedRandomAccessList構築セットを使用し、そうでない場合はjava.util.Collections.SynchronizedList構築セットを使用します。

ソースコード内の対応する追加操作ロジックは次のとおりです。
ここに画像の説明を挿入

synchronizedコードブロックを同期する方法を取り、データの追加操作のロックを実現してください!

  • メソッド2:new CopyOnWriteArrayList();
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListTest {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        List<String> lists = new CopyOnWriteArrayList<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
    
    
            new Thread(()->{
    
    
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

ソースコードの
ここに画像の説明を挿入
ここに画像の説明を挿入
概要は次のとおりです。明らかに、ロジックは次のとおりです。

1. addメソッドを呼び出した後、java.util.concurrent.locks.ReentrantLockオブジェクト情報を取得します。
2、lock.lock()ロックを取得するために呼び出します!
3.元の配列オブジェクトをコピーし、元の配列+1のサイズで新しい配列を作成します。
4.新しいデータを新しい配列に配置します。
5.最後に操作を行うと、ロックが解除されます。

パフォーマンスの側面

JUCパッケージでのロック操作は、同期よりもパフォーマンスが優れています。

おすすめ

転載: blog.csdn.net/qq_38322527/article/details/114703142