Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaでArrayListを同期化する2つの方法:synchronizedList()とCopyOnWriteArrayListの使い方

ArrayListAbstractListクラスのサブクラスであり、サイズが動的に変化する要素のコレクションを格納するために使用されます。新しい要素を追加するとリストは自動的に拡張され、要素を削除すると縮小します。このため、ArrayListは「リサイズ可能な配列」や「動的配列」と呼ばれることもあります。また、ArrayListは重複した値やnull値を許容するという特徴もあります。

ただし、通常のArrayListはスレッドセーフではないため、マルチスレッド環境で使用する場合は同期化(シンクロナイズ)が必要です。JavaでArrayListを同期化する方法は主に以下の2つがあります。

方法1:Collections.synchronizedList()メソッドを使う

synchronizedList()メソッドは、Javaのコレクションを同期化するために用意されているユーティリティメソッドです。既存のArrayListをラップすることで、スレッドセーフなListを実現できます。

構文

public static List<T> synchronizedList(List<T> list)

使用例

import java.util.*;
public class SynchronizedListTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("IND");
        list.add("AUS");
        list.add("WI");
        list.add("NZ");
        list.add("ENG");
        List<String> synlist = Collections.synchronizedList(list);
        synchronized(synlist) {
            Iterator<String> itr = synlist.iterator();
            while(itr.hasNext()) {
                String str = itr.next();
                System.out.println(str);
            }
        }
    }
}

実行結果

IND
AUS
WI
NZ
ENG

注意点として、イテレータを使用してリストを走査する場合、synchronizedブロックで明示的にロックを取得する必要があります。これは、イテレーション中に他のスレッドによる変更が発生するとConcurrentModificationExceptionがスローされる可能性があるためです。

方法2:CopyOnWriteArrayListクラスを使う

CopyOnWriteArrayListは、指定されたコレクションの順序どおりに要素のリストを作成します。このクラスはスレッドセーフな同時アクセスを実現するArrayListの代替手段です。リストが変更(追加・削除など)されるたびに、内部の配列の新しいコピーが作成される仕組みになっています。

構文

public class CopyOnWriteArrayList<E> extends Object implements List<E>, RandomAccess, Cloneable, Serializable

使用例

import java.util.*;
import java.util.concurrent.*;
public class CopyOnWriteArrayListTest {
    public static void main(String[] args) {
        CopyOnWriteArrayList list = new CopyOnWriteArrayList();
        list.add("Java");
        list.add("Scala");
        list.add("Python");
        list.add("Selenium");
        list.add("ServiceNow");
        System.out.println("同期化されたArrayListの表示: ");
        Iterator itr = list.iterator();
        while(itr.hasNext()) {
            String str = itr.next();
            System.out.println(str);
        }
    }
}

実行結果

同期化されたArrayListの表示:
Java
Scala
Python
Selenium
ServiceNow

どちらの方法を選ぶべきか?

Collections.synchronizedList()は、読み書きともにロックを行うため、操作頻度が高い場合に適しています。一方、CopyOnWriteArrayListは書き込み時に配列全体をコピーするためオーバーヘッドが大きいものの、読み取り処理にはロックが不要で、読み取りが多く書き込みが少ないケースに向いています。用途に応じて適切な方法を選択しましょう。

  1. JavaのJRadioButtonMenuItemとは?メニュー項目の作成方法とサンプルコードを解説

    JRadioButtonMenuItemは、Java SwingのJMenuItemクラスを継承したサブクラスです。同じグループに属する複数のメニュー項目の中から1つだけを選択できるラジオボタン形式のメニュー項目で、選択された項目にはその選択状態が表示されます。 複数のJRadioButtonMenuItemをButtonGroupオブジェクトに追加することでボタングループを形成できます。グループ内のいずれかの項目が選択されると、その他のすべてのラジオボタンメニュー項目は自動的に選択解除されます。この仕組みにより、設定画面などで「排他的な選択」を簡単に実現できます。 構文 public cla

  2. JavaのJListで使える選択モードは何種類?3つのモードの違いを解説

    JListは、JComponentクラスを継承したSwingコンポーネントの一つで、オブジェクトのリストを画面に表示し、ユーザーがその中から1つ以上の項目を選択できるようにするためのものです。 JavaのJListには、用途に応じて使い分けられる3種類の選択モードが用意されています。 ListSelectionModel.SINGLE_SELECTION:一度に選択できるのは、リスト内の1つのインデックスだけです。 ListSelectionModel.SINGLE_INTERVAL_SELECTION:一度に選択できるのは、1つの連続した区間(連続するインデックスの範囲)だけです。 Lis