Maison > Questions et réponses > le corps du texte
Vector或Collections.synchronizedList为什么get方法要加锁?CopyOnWriteArrayList并没有。
我觉得读的时候不加锁应该没问题吧?读时候加锁有什么意义?能确保读到最新值?那么直接给Object[] elementData
加volatile
关键字保证可见性。
我也知道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);
}
PHP中文网2017-04-18 09:46:03
Chaque thread en Java possède sa propre mémoire de travail, qui peut être comprise comme une copie de la mémoire principale. Si volatile est utilisé, il ne peut garantir qu'il est immédiatement lisible sur la mémoire principale, et ne peut garantir la synchronisation atomique avec la mémoire de travail de chaque thread
Même si vous n'utilisez pas volatile, mais ajoutez seulement synchronisé à l'opération d'écriture, mais pas à l'opération de lecture, il n'y a pas seulement le problème de ne pas pouvoir lire la dernière valeur, le plus gros problème est la synchronisation de la mémoire de travail du thread et de la mémoire principale Imaginez la situation suivante :
Entier i = 0
un fil donne i + 1
Pendant que a effectue cette opération +1, le thread b lit i dans sa propre mémoire de travail. À ce moment, i est toujours 0 car la lecture n'est pas verrouillée
Le thread a termine l'exécution, i = 1, puis synchronisé avec la mémoire principale
b effectue une opération +1 sur i. Puisque a a libéré le verrou en écriture, b peut écrire, mais puisque i dans sa propre mémoire de travail est 0, i est toujours 1 après +1
L'opération b est terminée et synchronisée avec la mémoire principale. Le i de la mémoire principale est toujours 1. Mais en fait on espère que j'ai 2 ans