広告

Java : ConcurrentModificationException (並列処理例外) - API使用例

ConcurrentModificationException (Java SE 19 & JDK 19) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。


概要

この例外は、オブジェクトの並行変更を検出したメソッドによってスローできます(そのような変更が許可されていないとき)。

クラス構成

ConcurrentModificationException は、並列処理によって、許可されていない状況でオブジェクトが変更されたときに発生する非チェック例外です。

例えば、ArrayList で反復処理 (for-eachループ文) をしている最中に、別のスレッドからリストに要素を追加すると発生します。

もし反復処理中に別スレッドからの変更を許容したい場合は、並列処理用のコレクションが使えます。
リストだと CopyOnWriteArrayList クラスがあります。

void test(List<Integer> list) throws InterruptedException {
    for (int i = 0; i < 5; i++) {
        list.add(i);
    }

    try (final var executor = Executors.newSingleThreadScheduledExecutor()) {

        executor.schedule(() -> {
            System.out.println("-- add value! --");
            list.add(9999);
        }, 5, TimeUnit.SECONDS);

        try {
            for (final var value : list) {
                System.out.println("value = " + value);
                TimeUnit.SECONDS.sleep(2);
            }
        } catch (ConcurrentModificationException e) {
            System.out.println("ConcurrentModificationException!");
        }
    }

    System.out.println("-- end --");
    System.out.println("list = " + list);
}
test(new ArrayList<>());

// 結果
// ↓
//value = 0
//value = 1
//value = 2
//-- add value! --
//ConcurrentModificationException!
//-- end --
//list = [0, 1, 2, 3, 4, 9999]

test(new CopyOnWriteArrayList<>());

// 結果
// ↓
//value = 0
//value = 1
//value = 2
//-- add value! --
//value = 3
//value = 4
//-- end --
//list = [0, 1, 2, 3, 4, 9999]

コンストラクタ

ConcurrentModificationException ()

詳細メッセージを指定しないでConcurrentModificationExceptionを構築します。

final var e = new ConcurrentModificationException();
System.out.println(e); // java.util.ConcurrentModificationException

ConcurrentModificationException (String message)

指定された詳細メッセージを持つConcurrentModificationExceptionを構築します。

final var e = new ConcurrentModificationException("abcd");
System.out.println(e); // java.util.ConcurrentModificationException: abcd
System.out.println(e.getMessage()); // abcd

ConcurrentModificationException (String message, Throwable cause)

指定された詳細メッセージおよび原因を使用して新規例外を構築します。

final var cause = new ConcurrentModificationException("XYZ");
final var e = new ConcurrentModificationException("abcd", cause);

System.out.println(e); // java.util.ConcurrentModificationException: abcd
System.out.println(e.getMessage()); // abcd

System.out.println(e.getCause()); // java.util.ConcurrentModificationException: XYZ
System.out.println(e.getCause().getMessage()); // XYZ

ConcurrentModificationException (Throwable cause)

指定された原因と詳細メッセージ((cause==null ? null : cause.toString()))を持つ新しい例外を構築します(通常、クラスとcauseの詳細メッセージを含みます)。

final var cause = new ConcurrentModificationException("XYZ");
final var e = new ConcurrentModificationException(cause);

// java.util.ConcurrentModificationException: java.util.ConcurrentModificationException: XYZ
System.out.println(e);
// java.util.ConcurrentModificationException: XYZ
System.out.println(e.getMessage());

System.out.println(e.getCause()); // java.util.ConcurrentModificationException: XYZ
System.out.println(e.getCause().getMessage()); // XYZ

Throwableで宣言されたメソッド

addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString

Java API 使用例 : Throwable」をご参照ください。


関連記事

ページの先頭へ