///////
Search
💫

자바의 synchronized 키워드에 대해 설명해주시고 Reentrant Lock와의 차이는 무엇인지 말씀해주세요.

synchronized 키워드

스레드가 하나의 자원을 사용하고자 할 때, 해당 스레드만 제외하고 나머지 스레드는 자원에 접근 못하도록 막는 것을 동기화라고 한다.
자바에서의 synchronized는 객체에 대한 동기화 로 이루어지며, 이는 동기화된 블록에는 한 시점에는 하나의 스레드만이 접근 및 실행 되도록 조정한다.

예시

public class ThreadSyncEx { public static void main(String[] args) { Runnable thread = new CreateThread(); // 2개의 작업 스레드 생성 Thread thread1 = new Thread(thread); Thread thread2 = new Thread(thread); thread1.setName("스레드1"); thread2.setName("스레드2"); thread1.start(); thread2.start(); } } class Money { // 현재 가지고 있는 금액 private int myMoney = 10000; public int getMyMoney() { return myMoney; } public boolean withdraw(int money) { // 가지고 있는 금액이 출금할 금액보다 크거나 같을 때만 출금 if (myMoney >= money) { // 스레드 동시 접근을 위한 코드 try { Thread.sleep(1000); } catch (Exception e) { System.out.println(e); } // 출금 myMoney -= money; return true; } return false; } } class CreateThread implements Runnable { Money myMoney = new Money(); public void run() { while (myMoney.getMyMoney() > 0) { // 1000 ~ 5000원씩 출금 int money = (int)(Math.random() * 5 + 1) * 1000; // 출금 실행 코드. 실패시 true 반환 boolean denied = !myMoney.withdraw(money); // 출금 과정 출력 if (denied) { System.out.println("출금 거부"); } else { System.out.printf("스레드: %s 출금: %d원 남은금액: %d원\\n", Thread.currentThread().getName(), money, myMoney.getMyMoney()); } } } }
Java
복사
// 출력 (실행할 때마다 결과는 달라진다.) 스레드: 스레드1 출금: 5000원 남은금액: 5000원 스레드: 스레드2 출금: 2000원 남은금액: 5000원 스레드: 스레드2 출금: 1000원 남은금액: 4000원 출금 거부 스레드: 스레드1 출금: 1000원 남은금액: 3000원 스레드: 스레드2 출금: 2000원 남은금액: -2000원 스레드: 스레드1 출금: 3000원 남은금액: -2000
Java
복사

synchronized 키워드를 임계 영역으로 지정할 메서드의 반환 타입 앞에 입력하여 메서드 전체를 임계 영역으로 설정할 수 있다

class Money { private int myMoney = 10000; public int getMyMoney() { return myMoney; } // 메서드 전체를 임계영역으로 설정 public synchronized boolean withdraw(int money) { if (myMoney >= money) { try { Thread.sleep(1000); } catch (Exception e) { System.out.println(e); } myMoney -= money; return true; } return false; } }
Java
복사
// 출력 스레드: 스레드1 출금: 1000원 남은금액: 9000원 스레드: 스레드2 출금: 2000원 남은금액: 7000원 스레드: 스레드1 출금: 4000원 남은금액: 3000원 출금 거부 출금 거부 스레드: 스레드1 출금: 3000원 남은금액: 0
Java
복사

Reentrant Lock이란?

ReentrantLock은 동기화된 메소드와 문장을 사용하여 액세스할 수 있는 암시적인 모니터 잠금 기능과 같은 기본적인 의미를 가진 Reentrant 상호 간의 상호 배제된 상호 배제 잠금을 의미한다.
잠금 영역과 잠금을 푸는 영역을 수동적으로 설정할 수 있다.
ReentrantLock 객체는 선언 시 private final로 선언한다.
동기화하고 싶은 구역의 앞부분에 참조 변수명.lock으로 해당 구문을 잠가준다. 그리고 동기화 내용을 try 안에 적어준 뒤, finally를 사용하여 참조 변수명.unlock하여 잠가둔 구역을 풀어준다.
//기본적인 사용법 class TestClass{ private ReentrantLock lock = new ReentrantLock(); // Lock 생성 public testMethod(){ lock.lock(); try{ //Critical Section } finally { lock.unlock(); } } }
Java
복사