동기화 메소드와 블록
- 스레드 작업이 끝날 때까지 객체에 잠금을 걸어 스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없게 함
출처, 이것이 자바다
출처, 이것이 자바다
동기화 메소드 및 블록 선언
- 인스턴스와 정적 메소드에 synchronized 키워드 붙임
출처, 이것이 자바다
- 동기화 메소드를 실행 즉시 객체는 잠금이 일어나고, 메소드 실행이 끝나면 잠금 풀림
- 메소드 일부 영역 실행 시 객체 잠금을 걸고 싶다면 동기화 블록을 만듦
출처, 이것이 자바다
package ch14.sec06.exam01;
//공유객체
public class Calculator {
//공유필드
private int memory;
public int getMemory() {
return memory;
}
//synchronized : 메소드에 동기화 작업. synchronized 유무에 따른 테스트 해보기
//동기화 메소드
public synchronized void setMemory1(int memory) {
this.memory = memory;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ": " + this.memory);
}
//불록 동기화 : 메소드내에서 일부 코드만 다른 스레드의 접근을 막을때 사용.
public void setMemory2(int memory) {
synchronized (this) {
this.memory = memory;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ": " + this.memory);
}
}
}
package ch14.sec06.exam01;
public class User1Thread extends Thread {
private Calculator calculator;
public User1Thread() {
setName("User1Thread");
}
public void setCalculator(Calculator calculator) {
this.calculator = calculator;
}
@Override
public void run() {
calculator.setMemory1(100);
}
}
package ch14.sec06.exam01;
public class User2Thread extends Thread {
private Calculator calculator;
public User2Thread() {
setName("User2Thread");
}
public void setCalculator(Calculator calculator) {
this.calculator = calculator;
}
@Override
public void run() {
calculator.setMemory2(50);
}
}
package ch14.sec06.exam01;
/*
스레드 : 동기화 예제
- 메인 스레드, user1Thread 스레드, user2Thread 스레드
*/
public class SyncronizedExample {
public static void main(String[] args) {
//스레드1, 2가 calculator1, calculator2 객체를 생성할 경우에는 동기화 작업이 필요가 없다.
//이유는 기억장소를 동시에 접근하는 상황이 발생되지 않기때문.
// Calculator calculator1 = new Calculator();
// Calculator calculator2 = new Calculator();
//공유자원으로 사용한 클래스 객체. 스레드1, 2가 동시에 사용할 객체.
Calculator calculator = new Calculator();
//스레드 객체 생성
User1Thread user1Thread = new User1Thread();
user1Thread.setCalculator(calculator);
user1Thread.start();
User2Thread user2Thread = new User2Thread();
user2Thread.setCalculator(calculator);
user2Thread.start();
}
}
출처, 이것이 자바다
wait( )과 notify( )를 이용한 스레드 제어
- 두 스레드 교대 실행 시 공유 객체는 두 스레드가 작업할 내용을 각각 동기화 메소드로 정함
- 한 스레드 작업 완료 시 notify() 메소드를 호출해 일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만들고, wait() 메소드를 호출하여 자신은 일시 정지 상태로 만듦
출처, 이것이 자바다
- notify(): wait()에 의해 일시 정지된 스레드 중 한 개를 실행 대기 상태로 만듦
- notifyAll(): wait()에 의해 일시 정지된 모든 스레드를 실행 대기 상태로 만듦
package ch14.sec06.exam02;
//공유객체
public class WorkObject {
//작업1. 예>생산자
public synchronized void methodA() {
Thread thread = Thread.currentThread(); //이 코드를 실행하는 실행스레드 참조.
System.out.println(thread.getName() + ": methodA 작업 실행");
notify(); //일시정지중인 소비자 스레드를 실행대기상태로 변경.
try {
wait(); //자신의 스레드를 일시정지상태
} catch (InterruptedException e) {}
}
//작업2. 예>소비자
public synchronized void methodB() {
Thread thread = Thread.currentThread(); //이 코드를 실행하는 실행스레드 참조.
System.out.println(thread.getName() + ": methodB 작업 실행");
notify(); //일시정지중인 생산자 스레드를 실행대기상태로 변경.
try {
wait(); //자신의 스레드를 일시정지상태
} catch (InterruptedException e) {}
}
}
package ch14.sec06.exam02;
//작업1 : 생산자 스레드
public class ThreadA extends Thread{
private WorkObject workObject;
public ThreadA(WorkObject workObject) {
setName("ThreadA");
this.workObject = workObject;
}
@Override
public void run() {
for(int i=0; i<10; i++) {
workObject.methodA();
}
}
}
package ch14.sec06.exam02;
//작업1 : 소비자 스레드
public class ThreadB extends Thread{
private WorkObject workObject;
public ThreadB(WorkObject workObject) {
setName("ThreadB");
this.workObject = workObject;
}
@Override
public void run() {
for(int i=0; i<10; i++) {
workObject.methodB();
}
}
}
package ch14.sec06.exam02;
/*
스레드 동기화 : 생산자, 소비자
스레드 : 메인 스레드, threadA, threadB
실행시 notify(), wait() 코드 유무에 따라 실행결과를 확인해야 한다.
*/
public class WaitNotifyExample {
public static void main(String[] args) {
WorkObject workObject = new WorkObject();
ThreadA threadA = new ThreadA(workObject);
ThreadB threadB = new ThreadB(workObject);
threadA.start();
threadB.start();
}
}
'라이브러리 활용 - 멀티 스레드' 카테고리의 다른 글
데몬 스레드 (1) | 2023.02.06 |
---|---|
스레드 안전 종료 (1) | 2023.02.06 |
스레드 상태 (1) | 2023.02.03 |
스레드 이름 (0) | 2023.02.03 |
작업 스레드 생성과 실행 (1) | 2023.02.03 |