Java/자바 정리
133. 스레드 충돌 막기 – synchronized로 동기화 처리
코딩하는냥이
2025. 5. 19. 12:53
반응형
멀티스레드 환경에서는 여러 스레드가 하나의 객체에 동시에 접근하게 되면,
데이터가 뒤섞이거나 원하는 결과가 출력되지 않는 문제가 발생할 수 있습니다.
이러한 문제를 방지하기 위해 synchronized 키워드를 사용하면,
동시에 하나의 스레드만 메서드에 접근하도록 제한할 수 있어 안전한 동작을 보장할 수 있습니다.
📦 Calculator.java
package ch14.sec06;
public class Calculator {
private int memory;
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public synchronized void setMemory1(int memory) {
setMemory(memory);
try {Thread.sleep(2000);} catch (Exception e) {}
System.out.println(Thread.currentThread().getName()+": " + this.memory);
}
public synchronized void setMemory2(int memory) {
setMemory(memory);
try {Thread.sleep(2000);} catch (Exception e) {}
System.out.println(Thread.currentThread().getName()+": " + this.memory);
}
}
📦 User1Thread.java
package ch14.sec06;
public class User1Thread extends Thread{
private Calculator calculator;
public void setCalculator(Calculator calculator) {
this.calculator = calculator;
}
public User1Thread() {
setName("User1Thread");
}
public void run() {
calculator.setMemory1(100);
}
}
📦 User2Thread .java
package ch14.sec06;
public class User2Thread extends Thread{
private Calculator calculator;
public void setCalculator(Calculator calculator) {
this.calculator = calculator;
}
public User2Thread() {
setName("User2Thread");
}
public void run() {
calculator.setMemory2(50);
}
}
📌 예제 코드
package ch14.sec06;
public class SynchronizedExample {
public static void main(String[] args) {
Calculator calculator = new Calculator();
User1Thread user1Thread = new User1Thread();
User2Thread user2Thread = new User2Thread();
user1Thread.setCalculator(calculator);
user2Thread.setCalculator(calculator);
user1Thread.start();
user2Thread.start();
}
}
💻 실행 결과
User1Thread: 100
User2Thread: 50
※ 스레드 실행 순서는 상황에 따라 달라질 수 있습니다. 하지만 synchronized 덕분에
데이터가 뒤섞이지 않고 안전하게 출력됩니다.
※ 실행 순서는 상황에 따라 다를 수 있지만, 두 스레드가 서로 영향을 주지 않고 순차적으로 출력되는 것을 확인할 수 있습니다.
💬 코드 설명
- Calculator 클래스에는 setMemory1()이라는 메서드가 있으며, 이 메서드에는 synchronized 키워드가 붙어 있습니다.
- synchronized가 붙은 메서드는 한 번에 하나의 스레드만 접근할 수 있기 때문에,
User1Thread가 setMemory1()을 실행하는 동안에는 User2Thread는 대기하게 됩니다. - Thread.sleep(2000)을 사용하여 작업을 일부러 지연시킴으로써,
스레드 충돌 없이 순차적으로 처리되는 결과를 관찰할 수 있도록 구성되어 있습니다.
💡 포인트 정리
- synchronized는 멀티스레드 환경에서 공유 자원에 동시에 접근하는 것을 방지합니다.
- 한 번에 하나의 스레드만 메서드를 실행할 수 있도록 하여, 데이터의 일관성과 안정성을 유지할 수 있습니다.
- 공유 객체가 있을 때는 항상 동기화를 고려해야 합니다.
📌정리하자면, synchronized는 멀티스레드 프로그래밍에서 가장 기본적이면서도 중요한 동기화 수단입니다.
여러 스레드가 하나의 메서드나 자원에 동시에 접근하지 않도록 막아주어
스레드 간의 충돌이나 데이터 손상을 방지할 수 있습니다.
이번 예제를 통해 synchronized가 적용된 경우와 그렇지 않은 경우의 차이를 명확하게 이해하셨으면 좋겠습니다.