Java Thread Synchronized(동기화)란 여러 개의 Thread가 한 개의 자원을 사용하고자 할 때,
해당 Thread만 제외하고 나머지는 접근을 못하도록 막는 것이다.
Multi-Thread로 인하여 동기화를 제어해야하는 경우가 생긴다.
synchronized 키워드를 사용하면, Multi-Thread 상태에서 동일한 자원을 동시에 접근하게 되었을 때 동시 접근을 막게 된다.
synchronized를 사용하는 방법은 아래와 같다.
1. 메서드에 synchronized 하기
- synchronized 를 붙이면 메소드 전체가 임계 영역으로 설정된다.
- 쓰레드는 synchronized 메소드가 호출된 시점부터 해당 메소드가 포함된 객체의 Lock을 얻어 작업을 수행하다가 메소드가 종료되면 Lock 을 반환한다.
2. 블록에 synchronized 하기
- 메소드 내의 코드 일부를 블럭{} 으로 감싸고 블럭 앞에 synchronized를 붙이는 것이다.
- 이때 참조변수는 Lock 을 걸고자 하는 객체를 참조하는 것이어야 한다.
- 이 영역 안으로 들어가면서부터 쓰레드는 지정된 객체의 Lock 을 얻게 되고, 이 블럭을 벗어나면 Lock 을 반납한다.
synchronized : 단 하나의 쓰레드만 실행할 수 있는 메소드 또는 블록을 말한다.
- 다른 쓰레드는 메소드나 블록이 실행이 끝날 때까지 대기해야 한다.
- wait(), notify(), notifyAll() 은 동기화 메소드 또는 블록에서만 호출 가능한 Object의 메소드
두개의 쓰레드가 교대로 번갈아 가며 실행해야 할 경우에 주로 사용한다.
- wait() 호출한 쓰레드는 일시 정지가 된다.
- notify() or notifyAll()을 호출하면 다른 쓰레드가 실행 대기 상태가 된다.
- synchronized를 대충 사용하면 퍼포먼스 저하, 예상치 못한 동작이 발생할 수 있다.
- 임계 영역은 멀티쓰레드 프로그램의 성능을 좌우하기 때문에 가능하면 메소드 전체에 Lock을 거는 것보다 synchronized 블럭으로 임계 영역을 최소화해서 보다 효율적인 프로그램이 되도록 노력해야 한다.
- 쓰레드는 자신의 run() 메소드가 모두 실행되면 자동적으로 종료된다.
아래 예제를 실행해서 결과가 나오는 걸 이해해야 한다.
synchronized 를 붙인 경우와 붙이지 않은 경우에 결과를 비교해보면 명확하게 이해가 될 것이다.
예제1
public class SynchThread extends Thread { |
public class SyncMainThread { |
실행결과
syncThread 가 완료될 때까지 기다린다.
0를 더한다.
1를 더한다.
2를 더한다.
3를 더한다.
4를 더한다.
Total Sum : 10
예제2 (동기화 개념을 명확히 이해하고자 한다면 아래 동영상 강좌를 꼭 들어라)
두개의 쓰레드가 교대로 번갈아 가며 실행해야 하는 경우에 주로 사용한다.
"이것이 자바다" 유투브 강좌 https://www.youtube.com/watch?v=hao05jNL2m8 35분부터 참조하면 설명이 잘 되어 있다. 아래 코드는 https://www.youtube.com/watch?v=7pNZr8cmjis 강좌에 나온 내용이다.
- wait() 를 호출해서 자기 자신은 일시 정지가 된다.
public class DataBox { } catch (InterruptedException e) { } catch (InterruptedException e) { System.out.println("ProducerThread가 생성한 데이터: " + data); } |
public class ProducerThread extends Thread { |
public class ConsumerThread extends Thread { |
public class WaitNotifyExam { |
실행 결과
ProducerThread가 생성한 데이터: Data-1
ConsummerThread가 읽은 데이터: Data-1
ProducerThread가 생성한 데이터: Data-2
ConsummerThread가 읽은 데이터: Data-2
ProducerThread가 생성한 데이터: Data-3
ConsummerThread가 읽은 데이터: Data-3
자바의 정석 13장 예제
public class SyncEx { |
'안드로이드 > Java 문법' 카테고리의 다른 글
[Java] 다형성 : 참조변수 형변환, 매개변수 다형성 (0) | 2020.07.08 |
---|---|
[Java] 접근 제어자(access modifier) (0) | 2020.07.08 |
Java Thread 상태 제어 - 안전한 종료 (0) | 2019.11.08 |
Java Thread 이해 및 Thread Life Cycle (0) | 2019.11.07 |
java TCP 소켓 프로그래밍 예제 (0) | 2019.11.06 |