자바 웹 개발자가 될거야/JAVA
[JAVA] 동기화 메소드 / synchronized
whitz
2021. 12. 9. 11:17
< 동기화 메소드 >
- 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있도록 임계 영역을 지정한 것을 말한다
- 사용 중인 객체를 다른 메소드가 변경할 수 없게 함
① synchronized
- 동기화 메소드를 만들려면 synchronized 키워드 붙이면 됨- 인스턴스와 정적 메소드 어디든 붙일 수 있음
public synchronized void method(){
임계영역 // 단 하나의 스레드만 실행
}
- 스레드가 동기화 메소드를 실행하는 즉시 객체 잠금일어나고 스레드가 동기화 메소드 실행 종료하면 잠금 풀림
- 동기화 메소드가 여러 개일 경우, 한 스레드 실행할 때 다른 동기화 메소드 실행할 수 없지만 일반 메소드는 실행 가능
② 예제
- 동기화하지 않으면 객체가 공유되면서 결과값이 다른 스레드에 의해 영향을 받을 수 있다.
public class MainThreadExample {
public static void main(String[] args) {
Calculator calculator = new Calculator();
User1 user1 = new User1();
user1.setCalculator(calculator);
user1.start();
User2 user2 = new User2();
user2.setCalculator(calculator);
user2.start();
}
}
public class Calculator {
private int memory;
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
try {
Thread.sleep(2000);
}catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+": "+this.memory);
}
}
public class User1 extends Thread{
private Calculator calculator;
public void setCalculator(Calculator calculator) {
this.setName("User1");
this.calculator=calculator;
}
@Override
public void run() {
calculator.setMemory(100);
}
}
public class User2 extends Thread{
private Calculator calculator;
public void setCalculator(Calculator calculator) {
this.setName("User2");
this.calculator = calculator;
}
@Override
public void run() {
calculator.setMemory(50);
}
}
· 동기화하지 않아서 User1이 원래 100이 나와야하는데 User2 영향으로 User2 스레드가 저장한 50을 출력하게 된다
- setMemory를 동기화 해보겠다
public class Calculator {
private int memory;
public int getMemory() {
return memory;
}
public synchronized void setMemory(int memory) {
this.memory = memory;
try {
Thread.sleep(2000);
}catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+": "+this.memory);
}
}
· 정상적으로 User1은 100을 출력하게된다
· 안정성은 보장되지만 효율은 낮아진다