Co to jest Lock(), UnLock(), ReentrantLock(), TryLock() i czym różni się od zsynchronizowanego bloku w Javie?]
Opublikowany: 2020-07-05
W tym samouczku omówimy Lock(), UnLock(), ReentrantLock(), TryLock() i jak różni się on od Synchronized Block w Javie.
Jeśli masz również poniższe pytania, to jesteś we właściwym miejscu.
- Blokady w Javie
- Przykład blokady Java i blokada współbieżności a synchronizacja
- Samouczek dotyczący współbieżności w języku Java — blokady wklęsłe
- synchronizacja – Prawidłowe użycie blokady/odblokowania dla Javy
- java – Synchronizacja vs Blokada
- przykład odblokowania blokady java
- mechanizm blokujący w java
- blokada java odblokuj inny wątek
Zacznijmy. Najpierw zrozummy każdy z tych terminów, a następnie omówimy przykład roboczy.
Zablokować():
java.util.concurrent.locks
. Blokada jest mechanizmem synchronizacji wątków, podobnie jak zsynchronizowane bloki, z wyjątkiem tego, że blokady mogą być bardziej wyrafinowane niż zsynchronizowane bloki Javy. Jest to interfejs i klasy zapewniające strukturę blokowania i oczekiwania na warunki, które różnią się od wbudowanej synchronizacji i monitorów.
Odblokować():
UnLock() zwalnia blokadę obiektu.
ReentrantLock():
ReentrantLock
jest własnością wątku jako ostatniego pomyślnego zablokowania, ale jeszcze go nie odblokowuje. Wątek wywołujący lock
zwróci, pomyślnie pobierając blokadę, gdy blokada nie jest własnością innego wątku. Metoda zwróci natychmiast, jeśli bieżący wątek jest już właścicielem blokady.
TryLock():
TryLock() uzyskuje blokadę tylko wtedy, gdy jest ona wolna w momencie wywołania.
Wskazówka-1
Jeśli po prostu blokujesz obiekt, wolałbym użyć synchronized.
1 2 3 |
Lock . lock ( ) ; youMethod ( ) ; // Throws a NullPointerException! Lock . unlock ( ) ; // Here you never release the lock! |
Podczas gdy z synchronizacją jest to bardzo jasne i niemożliwe do pomyłki:
1 2 3 |
synchronized ( myObject ) { doSomethingNifty ( ) ; } |
Przykładowe szczegóły:
- Utwórz klasę: CrunchifyLockTutorial.java
- Twórz klasy wewnętrzne: Company i CrunchifyLoop
- Z Main stwórz dwa obiekty klasy Company
- Uruchom pętlę wątku dla 10 na tych obiektach
- Podczas gdy Firma1 rozmawia z Firmą2 – blokuje obiekt. Jeśli w tym samym czasie — jeśli
Company2
chce rozmawiać zCompany1
, to mówi — Konflikt — Blokada już istnieje. (Obie firmy już rozmawiają).
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 ( ) ) ; } } } } |
Wyjście:
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 |
Wskazówka-2

Wszystko, co narzędzia w java.util.concurrent
, można osiągnąć za pomocą prymitywów niskiego poziomu, takich jak synchronized
, volatile
lub wait
.