ホームページ  >  記事  >  Java  >  Java JUC は List セキュリティ クラスのコレクションをどのように操作しますか?

Java JUC は List セキュリティ クラスのコレクションをどのように操作しますか?

WBOY
WBOY転載
2023-04-30 09:10:06688ブラウズ

安全でないコレクション

シングルスレッド アプリケーションでは、通常、 new ArrayList() を使用して、反復可能なデータを格納する List コレクションを指定します。

しかし、マルチスレッドでは、予期せぬ問題が頻繁に発生します。コードは次のとおりです:

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 言語では、新しい List コレクションである 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 エラー メッセージは表示されません。

データの安全な運用を保証できるのはなぜですか?

Java JUC怎么操作List安全类的集合

メソッド実行呼び出し元をロックする同期を採用し、追加操作のマルチスレッド セキュリティを確保します。

JUC のセキュリティ リスト コレクション

JUC パッケージでは、セキュリティ コレクションを作成する次の方法が提供されます。

  • 方法 1: 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 JUC怎么操作List安全类的集合

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

ソース コード内の対応する追加操作ロジックは次のとおりです。

Java JUC怎么操作List安全类的集合

同期化された同期コード ブロック メソッドを採用してデータを追加します。ロックを実現する操作!

  • #方法 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();
        }
    }
}
ソース コードの導入部は次のとおりです。

Java JUC怎么操作List安全类的集合

Java JUC怎么操作List安全类的集合

明らかに、ロジックは次のとおりです。

  1. add メソッドを呼び出した後、java.util を取得します。 .concurrent.locks .ReentrantLock オブジェクトの情報。

  2. lock.lock() を呼び出してロックを取得します。

  3. 元の配列オブジェクトをコピーし、元の配列サイズ 1 の新しい配列を作成します。

  4. 新しいデータを新しい配列に入れます。

  5. 任意の操作を行うと、最終的にロックが解除されます。

パフォーマンスの点での

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

以上がJava JUC は List セキュリティ クラスのコレクションをどのように操作しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。