공부의 정리 및 복습을 위한 기록입니다.
스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없게 하려면 스레드 작업이 끝날 때까지 객체에 잠금을 거어서 다른 스레드가 사용할 수 없도록 해야한다.
멀티 스레드에서 단 하나의 스레드만 실행할 수 있는 영억을 '임계 영역' 이라 한다.
JAVA에서는 임계 영역을 지정하기 위해 '동기화 메소드'를 제공한다.
동기화 메소드를 만드려면 메소드 선언부에 synchronized 키워드를 붙이면 된다.
public synchronized void method (){
//임계 영역
}
위와같이 synchronized 키워드를 사용하여 선언하면 된다.
예제를 보며 정리를 해보려한다.
Calculator 클래스의 코드는 아래와 같다.
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과 user2 클래스는 아래와 같다.
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);
}
}
위와 같은 클래스가 있고
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();
}
위와 같이 실행할 수 있는 메인 클래스가 있을때
synchronized키워드가 없다면
실행결과는
User1: 50
User2: 50
혹은
User1: 100
User2: 100
와 같이 나온다
이는 스레드의 동시성과 메모리의 공유 때문인데
Calculator클래스의 memory 필드는 두 스레드가 공유하는 변수기 때문이다.
두 스레드가 공유하는 memory라는 필드에 동시에 접근하기 때문에 synchronized 키워드를 사용하여 두 스레드간의 안정성을 확보해야한다.
synchronized 키워드를 사용하여 실행하면
User1 스레드가 setMemory에 진입할 때 synchronized 키워드가 있으므로 Calculator객체에 대한 잠금이 일어나고 User2 스레드는 대기상태가 된다.
User1 스레드가 setMemory메소드에 대한 실행이 종료된다면 잠금이 풀려 User2 스레드가 접근할 수 있게된다.
따라서 동기화메소드를 이용하여 실행을 시킨다면
실행결과는
User1: 100
User2: 50
위와 같이 나오게 되는걸 알 수 있다.
이렇게 동기화메소드를 사용하여 멀티스레드 환경에서 데이터의 일관성과 안전성을 보장할 수 있다.
하지만 너무 많은 동기화메소드사용은 잠금과 해제 과정에서 시간이 소요되며 다른 스레드는 대기상태에 들어가 이 또한 실행 시간이 지연될 수 있다. 따라서 프로그램의 성능저하가 발생할 수 있기 때문에 적절히 사용하는것이 좋을 것 같다.
공부하며 정리와 복습을 위해 저장한 기록입니다. 틀린 부분 및 개선할 부분이 있다면 알려주시면 감사하겠습니다 !