[Java Thread] 자바 스레드 동기화 Synchronized
Synchronized 키워드
- 한스레드만이 독점적으로 실행되어야 하는 부분(동기화 코드의) 표시하는 키워드
- 임계영역
- 메소드 전체 블럭
- 일부분 코드 블럭
모니터란? 객체를 독점적으로 사용할수 있는 권한
모니터를 먼저 소유한 스레드가 몬티너 내놀때까지 다른스레드는 기다린다
동기화 객체
두개이상의 스레드 사이에 동기화 작업에 사용되는객체
동기화 메소드
- synchonized블럭 내에서만 사용해야됨
wait()
- Object 클래스가 가진 메소드이다.
- 다른 스레드가 notify() 불러줄떄까지 기다린다.
notify()
- wait()로 인해 대기중인 스레드 깨우고 RUNABLE을 만든다.
- 2개이상의 스레드가 대기중이라도 오직 한개의 스레드만 꺠워 RUNABLE한다.
notifyAll()
- wait()를 호출로 인해 대기중인 모든스레드를 깨워버린다.
스레드 동기화는 크리티컬 섹션 임계영역을 서로 상호 배제 해주는 것이다.
C와 약간 스타일은 다르지만... 유형은 비슷하다 볼수있다.
- 크리티컬 섹션 임계영역의 변수 SUM이 존재한다.
- 2개의 스레드가 1개의 변수를 공유하는것이다..
- Synchorinzed를 사용하지 않는다면 임계영역 상호배제가 이루어지지않는다.
동기화를 사용한 소스코드
public class SynchronizedEx { public static void main(String[] args) { // 동기화 객체 선언 SyncObject obj = new SyncObject(); //스레드 객체 선언 Thread th1 = new WorkerThread("지연", obj); Thread th2 = new WorkerThread("은정", obj); th1.start(); // 스레드 시작 th2.start(); } } class SyncObject{ // 동기화 클래스 int sum=0; // 공유영역 synchronized void add(){ int n = sum; Thread.currentThread().yield(); // 현재스레드 양보해라 값을더하는동안 n+=10; sum = n; // sum을 덮어라 자기값으로 System.out.println(Thread.currentThread().getName() + " : " + sum); } int getSum(){ return sum; } } class WorkerThread extends Thread{ SyncObject sObj; // 동기화 객체 선언 //생성자 WorkerThread(String name, SyncObject sObj){ super(name); this.sObj = sObj; } public void run(){ int i=0; while(i<10){ sObj.add(); // 동기화 덧셈호출 i++; } } }
동기화를 사용하지않은 소스코드
synchronized void add(){ 를..........
void add() 로 바꿔주고Thread.currentThread().yield(); 를 사용하지않는다...그러면 스레드 동기화 기능이 사라짐 이렇게 테스트하면됨
동기화를 사용하지 않은 결과
EunJung : 20
EunJung : 30
EunJung : 40
JiYeon : 20
JiYeon : 60
JiYeon : 70
EunJung : 70
EunJung : 90
EunJung : 100
EunJung : 110
EunJung : 120
EunJung : 130
EunJung : 140
JiYeon : 80
JiYeon : 150
JiYeon : 160
JiYeon : 170
JiYeon : 180
JiYeon : 190
JiYeon : 200
동기화를 사용한 결과
JiYeon : 10
JiYeon : 20
JiYeon : 30
JiYeon : 40
JiYeon : 50
JiYeon : 60
JiYeon : 70
JiYeon : 80
JiYeon : 90
JiYeon : 100
EunJung : 110
EunJung : 120
EunJung : 130
EunJung : 140
EunJung : 150
EunJung : 160
EunJung : 170
EunJung : 180
EunJung : 190
EunJung : 200
Plus Alpha
위에 방법은 메소드로 특정 행동을 정의해놓은것을 불러서 하는 방식이고
변수에만 효과 주려면 이와 같디 하면된다.
예) buf라는 변수에 zz문자를 추가하는데, 동기화를 시켜서 추가하는
synchronized (buf) {
buf += "zz";
}