-1

私は次のケースを持っています、

public class Test {

    private static final int MAX_NUMBER = 10_00_00;

    public static void main(String[] args) {
        List<Integer> list = new CopyOnWriteArrayList<>();

        long start = System.nanoTime();
        for(int i = 0; i < MAX_NUMBER; i++) {
            list.add(i * 2);
        } 
        long end = System.nanoTime();
        System.out.println(((end - start) / Math.pow(10, 9)));
    }

}

出力

6.861539857

これは、約 100 秒かかったのに比べて、かなりゆっくりと要素を追加します。ドキュメントで理由を知りましたが、ArrayList0.004690843

ArrayList基になる配列の新しいコピーを作成することによって、すべての変更操作 (追加、設定など) が実装されるのスレッドセーフなバリアント。

したがって、私の理解では、このリストに新しい要素を追加するたびに、新しい新しい配列が作成され、この配列の最後のインデックスに要素が追加されます。ロックインaddメソッドを見つけましたが、それとは別に、そのメソッドは実際に毎回新しい配列を作成しています。

私が自分のプログラムを増やしMAX_NUMBERたとき10_00_000、プログラムは実行され続け、決して終了しません(そうなるでしょうが、私はそれほど長く待つことはできません)。

Collections.synchronizedList速度でスレッドセーフが必要な場合は、より良い選択だと思います。私はそれを使用し、それは約かかりました0.007673728

私の質問:

  1. 内部的に新しい配列を作成するのはなぜスレッドセーフがこれに関連しているのでしょうか?
  2. の場合、なぜそんなに時間がかかったのMAX_NUMBER = 10_00_000ですか?( で約6秒かかったようにMAX_NUMBER = 10_00_00)これは、ミュータティブ操作が毎回新しい配列を作成するために発生していますか?
  3. CopyOnWriteArrayListこれは、膨大な数の要素があり、他のものを選択した方がよい場合にパフォーマンスが低下することを意味しますか (つまりCollections.synchronizedList)?
  4. CopyOnWriteArrayListこれが、パブリック API で通常見られない理由ですか? これ以外に欠点はありますか?
4

1 に答える 1