Bagaimanakah Saya Boleh Mendapatkan ConcurrentModificationException Walaupun Menggunakan Synchronized?
Adalah perkara biasa untuk mengandaikan bahawa menggunakan kata kunci yang disegerakkan menghalang semua isu konkurensi. Walau bagaimanapun, ia hanya memastikan bahawa satu utas pada satu masa boleh mengakses blok kod yang disegerakkan. Ia tidak menghalang pengubahsuaian pada koleksi diulangi.
Pertimbangkan kod berikut:
public synchronized X getAnotherX() { if (iterator.hasNext()) { X b = iterator.next(); String name = b.getInputFileName(); ... return b; } else { return null; } }
Pengepala pengisytiharan yang disegerakkan hanya memastikan bahawa keseluruhan kaedah dilaksanakan oleh satu urutan pada satu masa. Walau bagaimanapun, ia tidak menghalang koleksi yang diakses oleh lelaran daripada diubah suai oleh urutan lain.
Mengapa ConcurrentModificationException Berlaku?
ConcurrentModificationException biasanya berlaku apabila anda mengubah suai koleksi yang diulang dalam gelung lelaran. Sebagai contoh, kod berikut akan menyebabkan pengecualian ini:
Iterator iterator = collection.iterator(); while (iterator.hasNext()) { Item item = (Item) iterator.next(); if (item.satisfiesCondition()) { collection.remove(item); } }
Dalam kes ini, anda harus menggunakan kaedah iterator.remove() untuk mengalih keluar elemen sebaliknya. Jika anda perlu menambah koleksi, anda tidak boleh bergantung pada kaedah yang disegerakkan. Walau bagaimanapun, jika anda berurusan dengan senarai, anda boleh menggunakan subjenis ListIterator, yang menyediakan kaedah add().
Atas ialah kandungan terperinci Mengapa Saya Mendapat ConcurrentModificationException Walaupun Menggunakan `synchronized`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!