En tant qu'outil permettant de partager simultanément des données et d'assurer la cohérence, les verrous ont plusieurs implémentations sur la plate-forme JAVA (telles que synchronisées et ReentrantLock, etc.). Ces verrous déjà écrits facilitent notre développement, mais la nature et le type spécifiques des verrous sont rarement mentionnés. Cette série d'articles analysera les noms et caractéristiques courants des verrous sous JAVA pour répondre à vos questions.
blocage du verrou
Les verrous bloquants, contrairement aux verrous rotatifs, modifient l’état d’exécution du thread.
Dans l'environnement JAVA, le thread Thread a les états suivants :
1. Nouvel état
2. État prêt
3. État d'exécution
4. État bloqué
5. État de décès
On peut dire que le verrou de blocage permet au thread d'entrer dans l'état de blocage et d'attendre. Lorsque le signal correspondant (réveil, heure) est obtenu, le thread peut entrer dans l'état prêt et entrer dans l'état d'exécution. par la compétition.
En JAVA, les méthodes qui peuvent entrer/sortir, bloquer l'état ou contenir des verrous de blocage incluent le mot-clé synchronisé (verrouillage de poids parmi eux), ReentrantLock, Object.wait()/notify(), LockSupport.park()/unpart()( jus souvent utilisé)
Voici un exemple de verrou de blocage JAVA :
verrouillage du package; importer java.util.concurrent.atomic.AtomicReferenceFieldUpdater; importer java.util.concurrent.locks.LockSupport; classe publique CLHLock1 { classe statique publique CLHNode { thread volatile privé isLocked } @SuppressWarnings ("inutilisé") CLHNode volatile privé tail; final statique privé ThreadLocal<CLHNode> LOCAL = new ThreadLocal<CLHNode>(); final statique privé AtomicReferenceFieldUpdater<CLHLock1, CLHNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(CLHLock1.class, CLHNode.class, "tail"); .set(nœud); CLHNode preNode = UPDATER.getAndSet(this, node); if (preNode != null) { preNode.isLocked = Thread.currentThread(); preNode = null LOCAL.set(node); void unlock() { CLHNode node = LOCAL.get(); if (!UPDATER.compareAndSet(this, node, null)) { System.out.println("unlock/t" + node.isLocked.getName()); LockSupport.unpark(node.isLocked } node = null }}
Ici, nous utilisons le verrou de blocage de LockSupport.unpark(). Cet exemple est modifié à partir du verrou CLH.
L'avantage du blocage des verrous est que les threads bloqués n'occuperont pas de temps CPU et n'entraîneront pas une occupation excessive du processeur, mais le temps d'entrée et le temps de récupération sont légèrement plus lents que les verrous rotatifs.
Dans le cas d’une concurrence féroce, les performances des verrous bloquants sont nettement supérieures à celles des verrous rotatifs.
La situation idéale est : utilisez des verrous rotatifs lorsque la concurrence entre les threads n'est pas féroce, et utilisez des verrous bloquants lorsque la concurrence est féroce.
(Fin du texte intégral)