Lock(), UnLock(), ReentrantLock(), TryLock()이란 무엇이며 Java의 Synchronized Block과 어떻게 다른가요?]
게시 됨: 2020-07-05
이 튜토리얼에서는 Lock(), UnLock(), ReentrantLock(), TryLock() 및 이것이 Java의 Synchronized Block과 어떻게 다른지 살펴보겠습니다.
아래 질문도 있는 경우 올바른 위치에 있습니다.
- 자바의 잠금
- Java 잠금 예제 및 동시성 잠금 대 동기화
- Java 동시성 자습서 – 재진입 잠금
- 동기화 – Java에 대한 적절한 잠금/잠금 해제 사용
- 자바 – 동기화 대 잠금
- 자바 잠금 해제 예
- 자바의 잠금 메커니즘
- 자바 잠금 잠금 해제 다른 스레드
시작하자. 1. 각각의 용어를 이해하고 실제 사례를 살펴보겠습니다.
잠그다():
java.util.concurrent.locks
. 잠금은 잠금이 Java의 동기화된 블록보다 더 정교할 수 있다는 점을 제외하고 동기화된 블록과 같은 스레드 동기화 메커니즘입니다. 기본 제공 동기화 및 모니터와 구별되는 조건을 잠그고 대기하기 위한 프레임워크를 제공하는 인터페이스 및 클래스입니다.
터놓다():
UnLock()은 Object에 대한 잠금을 해제합니다.
재진입 잠금():
ReentrantLock
은 마지막으로 성공적으로 잠금이 해제되었지만 아직 잠금 해제되지 않은 스레드가 소유 합니다. lock
을 호출하는 스레드는 잠금을 다른 스레드가 소유하지 않은 경우 성공적으로 잠금을 획득하여 반환됩니다. 현재 스레드가 이미 잠금을 소유하고 있으면 메서드가 즉시 반환됩니다.
TryLock():
TryLock()은 호출 시 사용 가능한 경우에만 잠금을 획득합니다.
팁-1
단순히 개체를 잠그는 경우 synchronized.
1 2 3 |
Lock . lock ( ) ; youMethod ( ) ; // Throws a NullPointerException! Lock . unlock ( ) ; // Here you never release the lock! |
동기화를 사용하면 매우 명확하고 잘못될 수 없습니다.
1 2 3 |
synchronized ( myObject ) { doSomethingNifty ( ) ; } |
예시 세부사항:
- 클래스 생성: CrunchifyLockTutorial.java
- 내부 클래스 생성: Company 및 CrunchifyLoop
- Main에서 Company 클래스의 두 개체를 만듭니다.
- 해당 개체에서 10에 대한 스레드 루프 시작
- Company1이 Company2와 통신하는 동안 개체를 잠급니다. 동시에 -
Company2
가Company1
과 대화하기를 원하면 - Conflicting - Lock이 이미 존재한다고 표시됩니다. (두 회사는 이미 논의 중입니다).
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 ( ) ) ; } } } } |
산출:
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 |
팁-2

java.util.concurrent
의 유틸리티가 synchronized
, volatile
또는 wait
와 같은 저수준 기본 요소로 수행하는 모든 작업을 수행할 수 있습니다.