Quand je lisais du code, j'ai frappé une classe appelée ʻAtomicReference`, donc je l'ai recherchée.
Selon la référence (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html)
Référence d'objet mise à jour atomiquement
Cette chose. Je ne sais pas si c'est tout, mais lors de l'exécution de la programmation simultanée, conservez les objets que vous souhaitez mettre à jour. Le «syncronize» est cher et le mot-clé «violatile» se brise lorsqu'il est écrit en même temps.
volatile
Déraillé, mais l'intention du mot-clé volatile
est de s'assurer que la référence de variable fait référence à la mémoire principale, pas au cache du processeur. Les variables sans ce mot-clé font généralement référence au cache du processeur. Dans un système avec plusieurs CPU, la même valeur n'est pas toujours référencée. Par conséquent, si vous ajoutez le mot-clé volatile
, il fera référence à la mémoire principale même si le processeur en cours d'exécution est différent, il est donc garanti qu'il se réfère au même. C'est pourquoi on l'appelle aussi «garantie de visibilité». Soit dit en passant, la signification de «volatile» est facile à changer.
private volatile int counter = 0;
Au fait, la description de ce site était excellente à comprendre. Puisqu'il s'agit d'un site appelé «Java Concurrency», vous pouvez vous attendre à d'autres articles.
AtomicReference
AtmoicReference, d'autre part, est un mécanisme de référencement et de mise à jour à partir de plusieurs threads sans verrouiller le verrou avec synchronized
.
get()
AtomicReference<Integer> atomic = new AtomicReference<>();
System.out.println("atomic: "+ atomic.get());
atomic = new AtomicReference<>(10);
System.out.println("atomic: " + atomic.get());
result
atomic: null
atomic: 10
Si vous spécifiez le type comme ceci, vous pouvez conserver la valeur ou y faire référence avec la méthode get ()
. Si vous ne passez rien, le constructeur sera initialisé avec null
.
set()
Un ensemble de valeurs.
atomic.set(100);
System.out.println("atomic: " + atomic.get());
result
atomic: 100
getAndUpdate()
Normalement, je ne pense pas que vous utilisiez beaucoup set ()
. S'il est mis à jour dans deux threads, ce sera la valeur mise à jour ultérieurement. Si ça va, ça va. Il existe donc des méthodes comme getAndUpdate ()
. Transmettez une expression lambda à mettre à jour en fonction de la valeur actuelle. Certaines méthodes ont l'ordre «mise à jour» et «get» inversé.
UnaryOperator operator = (v) -> (Integer)v + 1;
System.out.println("atomic getAndUpdate: " + atomic.getAndUpdate(operator));
System.out.println("atomic after getAndUpdate: " + atomic.get());
System.out.println("atomic updateAndGet: " + atomic.updateAndGet(operator));
result
atomic getAndUpdate: 20
atomic after getAndUpdate: 21
atomic updateAndGet: 22
compareAndSet()
Certaines méthodes n'écrivent que lorsque la valeur est attendue. La valeur de retour est boolean
, vous pouvez donc dire si c'était la valeur attendue. Cela garantit qu'il n'a été mis à jour dans aucun autre thread.
#À ce stade, la valeur est 22
atomic.compareAndSet(23, 100);
System.out.println("compareAndSet maybe not updated: " + atomic.get());
result
compareAndSet maybe not updated: 22
Au fait, il y avait une méthode appelée faibleCompareAndSet
, et le résultat était le même, alors qu'est-ce que c'est? Si vous y réfléchissez, l'implémentation est la même que compareAndSet
jusqu'à Java8, et à partir de Java9, elle semble être obsolète, alors oubliez-la.
Reference
Recommended Posts