java - 关于线程安全List读时加锁的问题
巴扎黑
巴扎黑 2017-04-18 09:44:03
0
1
690

Vector或Collections.synchronizedList为什么get方法要加锁?CopyOnWriteArrayList并没有。
我觉得读的时候不加锁应该没问题吧?读时候加锁有什么意义?能确保读到最新值?那么直接给Object[] elementDatavolatile关键字保证可见性。
我也知道CopyOnWriteArrayList修改是每次重新建一个elementData,但就算不是重新建,读时不加锁有什么问题?请赐教。

//以下是CopyOnWriteArrayList的代码:
@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
    return (E) a[index];
}
/**
 * {@inheritDoc}
 *
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E get(int index) {
    return get(getArray(), index);
}

//以下是Vector的代码:
public synchronized E get(int index) {
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);

    return elementData(index);
}
巴扎黑
巴扎黑

membalas semua(1)
洪涛

Setiap thread dalam Java mempunyai memori kerja sendiri, yang boleh difahami sebagai salinan memori utama. Jika tidak menentu digunakan, ia hanya boleh menjamin bahawa ia boleh dibaca serta-merta pada memori utama, dan tidak dapat menjamin penyegerakan atom dengan memori kerja setiap utas

Walaupun anda tidak menggunakan volatile, tetapi hanya menambah disegerakkan pada operasi menulis, tetapi tidak pada operasi membaca, bukan sahaja masalah tidak dapat membaca nilai terkini, masalah yang lebih besar ialah penyegerakan ingatan kerja benang dan ingatan utama Bayangkan Situasi berikut:

  1. Integer i = 0

  2. benang memberikan i + 1

  3. Semasa a melakukan operasi +1 ini, utas b membaca i ke dalam ingatan kerjanya sendiri Pada masa ini, i masih 0 kerana bacaan tidak dikunci

  4. Benang a menyelesaikan pelaksanaan, i = 1, dan kemudian disegerakkan ke memori utama

  5. b melakukan operasi +1 pada i Memandangkan a telah mengeluarkan kunci tulis, b boleh menulis, tetapi kerana i dalam ingatan kerjanya sendiri ialah 0, i masih 1 selepas +1

  6. Operasi b selesai dan disegerakkan ke memori utama i memori utama masih 1. Tetapi sebenarnya kami berharap saya adalah 2

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan