Qu'est-ce que Lock(), UnLock(), ReentrantLock(), TryLock() et en quoi est-ce différent de Synchronized Block en Java ?]
Publié: 2020-07-05
Dans ce didacticiel, nous allons passer en revue Lock(), UnLock(), ReentrantLock(), TryLock() et la différence avec Synchronized Block en Java.
Si vous avez également des questions ci-dessous, vous êtes au bon endroit.
- Verrous en Java
- Exemple de verrouillage Java et verrouillage de la concurrence vs synchronisation
- Tutoriel Java Concurrency - Verrous réentrants
- synchronisation - Utilisation correcte du verrouillage/déverrouillage pour Java
- java – Synchronisation vs Verrouillage
- exemple de déverrouillage de verrouillage java
- mécanisme de verrouillage en java
- java lock déverrouiller différents threads
Commençons. Tout d'abord, comprenons chacun de ces termes, puis nous passerons en revue l'exemple de travail.
Fermer à clé():
java.util.concurrent.locks
. Un verrou est un mécanisme de synchronisation de thread comme les blocs synchronisés, sauf que les verrous peuvent être plus sophistiqués que les blocs synchronisés de Java. Il s'agit d'interfaces et de classes fournissant un cadre pour le verrouillage et l'attente de conditions distinctes de la synchronisation et des moniteurs intégrés.
Ouvrir():
UnLock() libère le verrou sur l'objet.
ReentrantLock() :
Un ReentrantLock
appartient au dernier thread qui s'est verrouillé avec succès, mais ne l'a pas encore déverrouillé. Un thread invoquant lock
retournera, acquérant avec succès le verrou, lorsque le verrou n'appartient pas à un autre thread. La méthode retournera immédiatement si le thread actuel possède déjà le verrou.
TryLock() :
TryLock() acquiert le verrou uniquement s'il est libre au moment de l'invocation.
Astuce-1
Si vous verrouillez simplement un objet, je préférerais utiliser synchronized.
1 2 3 |
Lock . lock ( ) ; youMethod ( ) ; // Throws a NullPointerException! Lock . unlock ( ) ; // Here you never release the lock! |
Alors qu'avec synchronisé, c'est super clair et impossible de se tromper :
1 2 3 |
synchronized ( myObject ) { doSomethingNifty ( ) ; } |
Détails de l'exemple :
- Créer une classe : CrunchifyLockTutorial.java
- Créer des classes internes : Company et CrunchifyLoop
- À partir de Main, créez deux objets de la classe Company
- Démarrer la boucle de thread pour 10 sur ces objets
- Pendant que Company1 parle à Company2, elle verrouille un objet. Si en même temps - si
Company2
veut parler àCompany1
alors il dit - Conflit - Le verrou existe déjà. (Les deux sociétés sont déjà en discussion).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
package crunchify . com . tutorial ; import java . util . Random ; import java . util . concurrent . locks . Lock ; import java . util . concurrent . locks . ReentrantLock ; /** * @author Crunchify.com * */ public class CrunchifyLockTutorial { public static void main ( String [ ] args ) { final Company crunchify = new Company ( "Crunchify" ) ; final Company google = new Company ( "Google" ) ; new Thread ( new CrunchifyLoop ( crunchify , google ) ) . start ( ) ; new Thread ( new CrunchifyLoop ( google , crunchify ) ) . start ( ) ; } // Class CrunchifyLoop static class CrunchifyLoop implements Runnable { private Company companyName1 ; private Company companyName2 ; public CrunchifyLoop ( Company companyName1 , Company companyName2 ) { this . companyName1 = companyName1 ; this . companyName2 = companyName2 ; } public void run ( ) { Random random = new Random ( ) ; // Loop 10 for ( int counter = 0 ; counter < = 10 ; counter ++ ) { try { Thread . sleep ( random . nextInt ( 5 ) ) ; } catch ( InterruptedException e ) { } companyName2 . crunchifyTalking ( companyName1 ) ; } } } // Class Company static class Company { private final String companyName ; // ReentrantLock: Creates an instance of ReentrantLock. This is equivalent to using ReentrantLock(false) private final Lock lock = new ReentrantLock ( ) ; // Constructor public Company ( String name ) { this . companyName = name ; } public String getName ( ) { return this . companyName ; } public boolean isTalking ( Company companyName ) { Boolean crunchifyLock = false ; Boolean googleLock = false ; try { // tryLock: Acquires the lock only if it is free at the time of invocation. crunchifyLock = lock . tryLock ( ) ; googleLock = companyName . lock . tryLock ( ) ; } finally { if ( ! ( crunchifyLock && googleLock)) { if (crunchifyLock) { // unlock: Releases the lock. lock.unlock(); } if ( googleLock ) { companyName . lock . unlock ( ) ; } } } return crunchifyLock && googleLock; } public void crunchifyTalking ( Company companyName ) { // Check if Lock is already exist? if ( isTalking ( companyName ) ) { try { System . out . format ( "I'm %s: talking to %s %n" , this . companyName , companyName . getName ( ) ) ; } finally { lock . unlock ( ) ; companyName . lock . unlock ( ) ; } } else { System . out . format ( "\tLock Situation ==> I'm %s: talking to %s, but it seems" + " we are already talking. Conflicting. %n" , this . companyName , companyName . getName ( ) ) ; } } } } |
Sortir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
I 'm Crunchify: talking to Google Lock Situation ==> I' m Google : talking to Crunchify , but it seems we are already talking . Conflicting . I 'm Google: talking to Crunchify I' m Google : talking to Crunchify I 'm Crunchify: talking to Google I' m Google : talking to Crunchify I 'm Google: talking to Crunchify I' m Crunchify : talking to Google Lock Situation == > I 'm Google: talking to Crunchify, but it seems we are already talking. Conflicting. Lock Situation ==> I' m Crunchify : talking to Google , but it seems we are already talking . Conflicting . Lock Situation == > I 'm Google: talking to Crunchify, but it seems we are already talking. Conflicting. I' m Crunchify : talking to Google I 'm Google: talking to Crunchify I' m Google : talking to Crunchify I 'm Crunchify: talking to Google I' m Google : talking to Crunchify Lock Situation == > I 'm Google: talking to Crunchify, but it seems we are already talking. Conflicting. Lock Situation ==> I' m Crunchify : talking to Google , but it seems we are already talking . Conflicting . I 'm Crunchify: talking to Google I' m Crunchify : talking to Google I 'm Crunchify: talking to Google I' m Crunchify : talking to Google |
Astuce-2

Vous pouvez réaliser tout ce que font les utilitaires de java.util.concurrent
avec les primitives de bas niveau telles que synchronized
, volatile
ou wait
.