스레드 동기화는 멀티스레딩 환경에서 여러 스레드가 공유 자원에 접근할 때 발생할 수 있는 문제를 해결하기 위한 기법입니다. 동기화는 특정 코드 블록이나 메서드가 동시에 여러 스레드에 의해 실행되지 않도록 보장하는 것입니다. 이를 통해 데이터 일관성을 유지하고, 경합 조건(Race Condition)을 방지할 수 있습니다.
쉽게 예를 들자면, 공유한 폴더에 한 사람씩만 데이터를 집어 넣을 수 있다 치자.
근데 두사람이 한번에 데이터를 집어넣으면 꼬이게 된다. 이런 경우를 방지하기 위해 한 사람이 모든 일을 완료 한 후 다른 사람이 들어가서 작업을 해야된다. 쓰레드 동기화를 통해 해결 할 수 있다.
일단 run()메소드를 찾아라!
syncronized{}로 감싸라!
형식>
public synchronized void deposit(int amount, String name) {
임계영역...
}
public void withdraw(int amount, String name) {
synchronized (this) {
임계영역...
}
}
자바에서는 synchronized 키워드를 사용하여 메서드나 코드 블록을 동기화할 수 있습니다.
아래 코드는 Atm 클래스를 통해 동기화된 입출금 메서드를 구현하고, 여러 사용자(UserAtm 클래스)가 동시에 ATM 기계를 사용하는 상황을 시뮬레이션합니다.
java코드 복사
package syncronized;
// 쓰레드 (동기화)
class Atm {
private int money;
public Atm(int money) { // 생성자 함수
this.money = money;
}
// 입금함수
public synchronized void deposit(int amount, String name) {
money += amount;
System.out.println(name + " : 입금금액 " + amount);
}
// 출금함수
public synchronized void withdraw(int amount, String name) {
if ((money - amount) > 0) {
money -= amount;
System.out.println(name + ": 출금금액 " + amount);
} else {
System.out.println(name + ": 출금못함(잔액 부족 ~~~)");
}
}
// 통장 잔고 함수
public synchronized void getMoney() {
System.out.println(" 잔액은: " + money);
}
}// Atm end
class UserAtm extends Thread {
Atm obj;
boolean flag = false;
public UserAtm(Atm obj, String name) {
super(name);
this.obj = obj;
}
@Override
public void run() { // 스레드 실행부 (구현부)
for (int i = 0; i < 2; i++) {
try {
sleep(50);
} catch (Exception e) {
e.printStackTrace();
}
if (flag) {
obj.deposit((int) (Math.random() * 10 + 2) * 100, getName());
} else {
obj.withdraw((int) (Math.random() * 10 + 2) * 100, getName());
}
flag = !flag;
obj.getMoney();
}
}
}// UserAtm end
public class MainEntry {
public static void main(String[] args) {
Atm at = new Atm(1000);
UserAtm user1 = new UserAtm(at, "김연아");
UserAtm user2 = new UserAtm(at, "박태환");
UserAtm user3 = new UserAtm(at, "세종");
user1.start();
user2.start();
user3.start();
}
}
money 변수는 ATM의 잔액을 나타냅니다.deposit 메서드는 입금 기능을 수행하며, synchronized 키워드를 사용하여 동기화됩니다.withdraw 메서드는 출금 기능을 수행하며, synchronized 키워드를 사용하여 동기화됩니다.getMoney 메서드는 현재 잔액을 출력하며, synchronized 키워드를 사용하여 동기화됩니다.Atm 객체를 참조하는 obj 변수를 가집니다.flag 변수는 입금과 출금을 번갈아 가며 수행하기 위해 사용됩니다.run 메서드는 Thread 클래스의 메서드를 오버라이드하여 스레드의 실행 로직을 정의합니다. 이 메서드에서는 무작위로 입금 또는 출금을 수행하고, 현재 잔액을 출력합니다.Atm 객체를 생성하고, 이를 공유하는 여러 UserAtm 스레드를 시작합니다.start 메서드를 호출하여 실행됩니다.