Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

멀티 Thread 프로그래밍에서의 동기화 본문

Java/다양한 기능

멀티 Thread 프로그래밍에서의 동기화

Seung__ 2021. 11. 3. 22:25

1. Critical Section과 semaphore


  • Critical Section은 두 개 이상의 thread가 동시에 에 접근 하는 경우 문제가 발생할 수 있기 때문에
    동시에 접근할 수 없는 영역
  • semaphore는 특별한 형태의 시스템 객체이며 get/release 두 개의 기능이 있다.
  • 한 순간 오직 하나의 thread만이 semaphore를 얻을 수 있고, 나머지 thread들은 대기(blocking)상태가 된다.
  • semaphore를 얻은 thread만이 critical section에 들어갈 수 있다.

노란색 : critical section

 

 

 

2. Park 과 Park2 가 동시에 Bank 자원에 접근하여

작업이 이루어지는 경우의 예제


  • Shared resource : Bank객체
  • Critical Section :  saveMoney(), minusMoney()
class Bank{
    private int money = 10000;

    public void saveMoney(int save){
        int m = getMoney();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        setMoney(m + save);
    }

    public void minusMoney(int minus){
        int m = getMoney();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        setMoney(m-minus);

    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

class Park extends Thread{
    public void run(){
        System.out.println("start save");
        SyncMain.bank.saveMoney(3000);
        System.out.println("saveMoney(3000) : " + SyncMain.bank.getMoney());
    }
}

class Park2 extends Thread{
    public void run(){
        System.out.println("start minus");
        SyncMain.bank.minusMoney(1000);
        System.out.println("minusMoney(1000) : " + SyncMain.bank.getMoney());
    }
}

public class SyncMain {

    public static Bank bank = new Bank();

    public static void main(String[] args) {

        Park p1 = new Park();
        p1.start();

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Park2 p2 = new Park2();
        p2.start();

    }
}
  • 어????왜 더해지는거만 반영이 됐지.. 뭐가 문제일까?
    • save가 먼저 시작되었는데, minusMoney()가 중간에 치고들어옴.. 
start save
start minus
minusMoney(1000) : 9000
saveMoney(3000) : 13000
  • 프로그램 흐름은 다음과 같다.
    • 여기서 Money는 Shared Resource이다. 
    • 따라서 saveMoney()가 실행되는 동안 , minusMoney()는 들어오면 안돼! 멈춰! 반대도 마찬가지.

 

 

 

3. synchronized


  • 동기화가 필요한 method에 synchronozed를 추가해주자.
  • 여러 개의 thread 가 같은 객체에 접근 할 경우, 동시에 접근 함으로써 오류가 발생
  • 동기화는 임계영역에 접근한 경우 공유자원을 lock 하여 다른 thread의 접근을 제어
  • 동기화를 잘못 구현하면 deadlock에 빠질 수 있다.
  • 방식에는 Synchronized 메서드, Synchronized 블럭 방식이 있다.

 

 

3.1  Synchronized 블럭 


  • block 방식이  좀 더 디테일하게 잡을 수 있음.
synchronized(얘를 블럭을 걸어라) {

      이 메서드가 실행될 동안;
}
    public synchronized void saveMoney(int save){

        synchronized (this){
            int m = getMoney();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            setMoney(m + save);
        }
    }

 

 

3.2 Synchronized 메서드


 

  • 객체의 메소드에 synchronized 키워드 사용
  • 현재 이 메서드가 속해있는 객체에 lock을 건다.
  • 위의 예제를 수정해보자.
    • 이와 같이 synchrhonized를 사용하면, Thread가 해당 method를 통해 공유 resource를 사용 시, 공유 resource(객체)에 다른 Thread가 접근하지 않도록 공유 resource를 lock 을 건다.

 

class Bank{
    private int money = 10000;

    public synchronized void saveMoney(int save){
        int m = getMoney();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        setMoney(m + save);
    }

    public synchronized void minusMoney(int minus){
        int m = getMoney();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        setMoney(m-minus);

    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
  • 짠!
start save
start minus
saveMoney(3000) : 13000
minusMoney(1000) : 12000

 

 

3.3 deadLock


  • 자바에서는 deadlock을 방지하는 기술이 제공되지 않으므로
  • 되도록이면 synchronized 메서드에서 다른 synchronized 메서드는 호출하지 않도록 한다.
  • 서로가 서로를 기다림 ㅋㅋㅋㅋ

 

 

 

4. GitHub  : 211003 Thread, synchronization


 

GitHub - bsh6463/various_functions

Contribute to bsh6463/various_functions development by creating an account on GitHub.

github.com

 

'Java > 다양한 기능' 카테고리의 다른 글

wait(), notify() 메서드 활용한 동기화 프로그래밍  (0) 2021.11.03
Thread 클래스의 메서드  (0) 2021.11.02
Thread  (0) 2021.11.01
Decorator Pattern 예제  (0) 2021.11.01
여러가지 입출력 클래스  (0) 2021.10.31
Comments