inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

자바 동시성 프로그래밍 [리액티브 프로그래밍 Part.1]

ReentrantLock API

ReentrantLock.lockInterruptibly() 질문

316

고래밥

작성한 질문수 9

0

먼저 강의 잘 듣고 있습니다.

 

강의 자료 202쪽에 보면 아래 그림과 같이 ReentrantLock.lockInterruptibly() 예제 코드가 작성되어 있는데요.

 

이 코드를 강의 소스코드 (LockInterruptiblyExample.java) 에 적용해 보았습니다. 적용한 코드는 아래와 같습니다.

 

public class LockInterruptiblyExample {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();

        Thread thread1 = new Thread(() -> {
            try {
                lock.lockInterruptibly(); // 락을 시도하며, 인터럽트가 들어오면 중단
                System.out.println("스레드 1이 락을 획득했습니다");
            } catch (InterruptedException e) {
                System.out.println("스레드 1이 인터럽트를 받았습니다");
            } finally {
                lock.unlock();
                System.out.println("스레드 1이 락을 해제했습니다");
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                lock.lockInterruptibly(); // 락을 시도하며, 인터럽트가 들어오면 중단
                try {
                    System.out.println("스레드 2가 락을 획득했습니다");
                } finally {
                    lock.unlock();
                    System.out.println("스레드 2가 락을 해제했습니다");
                }
            } catch (InterruptedException e) {
                System.out.println("스레드 2가 인터럽트를 받았습니다");
            }
        });

        thread1.start();
        thread2.start();
        thread1.interrupt();
//        thread2.interrupt();

        try {
            Thread.sleep(500);
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}

 

이 코드를 실행했을 때, 아래 이미지와 같이 IllegalMonitorStateException 이 발생했는데요.

 

아마 try ~ catch ~ finally 블록에 의한 문제가 아닐까 싶습니다. 이 부분이 어떻게 동작하여 오류가 발생한 건지 궁금한데, 답변 해주시면 감사하겠습니다.

java 동시성 multithread synchronisation

답변 1

0

정수원

위 코드에서 IllegalMonitorStateException가 발생하는 원인은 unlock 메서드가 락을 획득하지 않은 스레드에 의해 호출되기 때문인데요

ReentrantLock 객체의 unlock 메서드는 락을 획득한 스레드만이 호출할 수 있습니다.

위 코드에서는 thread1이 인터럽트될 때 락을 획득하지 않은 상태에서 thread1 이 finally 에서unlock을 호출하게 되어 예외가 발생하고 있습니다.

그래서 다음과 같이 할 수 있습니다.

Thread thread1 = new Thread(() -> {
    try {
        lock.lockInterruptibly(); // 락을 시도하며, 인터럽트가 들어오면 중단
        System.out.println("스레드 1이 락을 획득했습니다");
    } catch (InterruptedException e) {
        System.out.println("스레드 1이 인터럽트를 받았습니다");
    } finally {
        if (((ReentrantLock) lock).isHeldByCurrentThread()) {
            lock.unlock();
            System.out.println("스레드 1이 락을 해제했습니다");
        }
    }
});

즉 finally 에서 현재 스레드가 락을 획득한 경우에만 unlock 을 호출하도록 하는 것입니다.

0

고래밥

thread1 이 lock.lockInterruptibly() 을 호출하기 전에 인터럽트 되었고, 곧바로 finally블록을 수행하면서 unlock을 시도(lock획득 안한 상태)하기 때문에 Exception이 발생한 것으로 이해했습니다.

답변 감사드립니다!

멀티스레드 단일스레드

0

56

0

new Condition 부분 질문

0

83

1

13:00 강의 내용 이해 질문

0

99

1

강의 출시 질문 있습니다.

0

117

1

InterruptedExceptionThreadStopExample 질문입니다.

0

94

2

instance.getMyField()의 값이 왜 다른가요?

0

115

1

해당 강의 내용 무단 도용 신고

0

211

2

Thread Waiting 상태 관련 질문 드립니다.

0

186

1

단일연산변수 api

0

126

0

synchronized 블럭과 메인메모리 반영

0

147

0

실무에서 자바가 제공하는 락을 사용하는 경우

1

243

1

뮤텍스나 세마포어는 busy waiting이 없는 게 맞을까요?

0

159

1

16:50부분에서 타입락 질문드립니다.

0

110

2

16분 7초 뮤텍스 코드 관련해 질문드립니다.

0

160

2

동기화가 보장된다고 하더라도 스레드간 데이터 불일치가 발생할 수 있지 않나요??

0

199

2

리액티브-part2

0

180

2

문자열 풀 값을 이용한 String 변수

0

207

2

스레드 라이브러리는 커널과 같은 역할을 하지 못하나요?

0

173

1

자식 프로세스를 쓰는 이유

0

186

1

커널 모드 전환시 질문이 있습니다!

0

146

1

[공유] setName 시 threadName이 1부터 시작하는 이유

0

178

1

synchronized = 모니터

0

285

2

Thread의 Context Switching 문의드립니다.

1

257

1

동기 & 논블록킹 질문 드립니다.

0

232

2