JavaπŸŽ€

Java μŠ€λ ˆλ“œ

Jeein0313 2023. 7. 3. 21:46

ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œ

 

ν”„λ‘œμ„ΈμŠ€ : μ‹€ν–‰ 쀑인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•˜λ©΄ μš΄μ˜μ²΄μ œλ‘œλΆ€ν„° 싀행에 ν•„μš”ν•œ 만큼의 λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήλ°›μ•„ ν”„λ‘œμ„ΈμŠ€κ°€ λœλ‹€.

 

ν”„λ‘œμ„ΈμŠ€λŠ” 데이터, 컴퓨터 μžμ›, μŠ€λ ˆλ“œλ‘œ κ΅¬μ„±λ˜λŠ”λ°, μŠ€λ ˆλ“œλŠ” 데이터와 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ ν™•λ³΄ν•œ μžμ›μ„ ν™œμš©ν•˜μ—¬ μ†ŒμŠ€ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œλ‹€.

즉, μŠ€λ ˆλ“œλŠ” ν•˜λ‚˜μ˜ μ½”λ“œ μ‹€ν–‰ 흐름이라고 λ³Ό 수 μžˆλ‹€.

 

메인 μŠ€λ ˆλ“œ

 

μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•˜λ©΄ κ°€μž₯ λ¨Όμ € μ‹€ν–‰λ˜λŠ” λ©”μ„œλ“œλŠ” main λ©”μ„œλ“œμ΄λ©°, 메인 μŠ€λ ˆλ“œκ°€ main λ©”μ„œλ“œλ₯Ό μ‹€ν–‰μ‹œμΌœμ€€λ‹€. 메인 μŠ€λ ˆλ“œλŠ” main λ©”μ„œλ“œμ˜ μ½”λ“œλ₯Ό μ²˜μŒλΆ€ν„° λκΉŒμ§€ μ°¨λ‘€λŒ€λ‘œ μ‹€ν–‰μ‹œν‚€κ³ , μ½”λ“œ 끝을 λ§Œλ‚˜κ±°λ‚˜ return문을 λ§Œλ‚˜λ©΄ 싀행을 μ’…λ£Œν•œλ‹€.

 

λ§Œμ•½, μ–΄λ–€ μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ†ŒμŠ€ μ½”λ“œκ°€ μ‹±κΈ€ μŠ€λ ˆλ“œλ‘œ μž‘μ„±λ˜μ—ˆλ‹€λ©΄, κ·Έ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹€ν–‰λ˜μ–΄ ν”„λ‘œμ„ΈμŠ€κ°€ 될 λ•Œ μ˜€λ‘œμ§€ 메인 μŠ€λ ˆλ“œλ§Œ κ°€μ§€λŠ” μ‹±κΈ€ μŠ€λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€κ°€ 될 것이닀. 반면, 메인 μŠ€λ ˆλ“œμ—μ„œ 또 λ‹€λ₯Έ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜μ—¬ μ‹€ν–‰μ‹œν‚¨λ‹€λ©΄ ν•΄λ‹Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ λ©€ν‹° μŠ€λ ˆλ“œλ‘œ λ™μž‘ν•˜κ²Œ λœλ‹€.

 

λ©€ν‹° μŠ€λ ˆλ“œ

 

ν•˜λ‚˜μ˜ ν”„λ‘œμ„ΈμŠ€λŠ” μ—¬λŸ¬ 개의 μŠ€λ ˆλ“œλ₯Ό κ°€μ§ˆ 수 있으며, 이λ₯Ό λ©€ν‹° μŠ€λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€λΌκ³  ν•œλ‹€. 

μ—¬λŸ¬ 개의 μŠ€λ ˆλ“œλ₯Ό κ°€μ§„λ‹€λŠ” 것은 μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŒμ„ μ˜λ―Έν•˜λ©°, 이λ₯Ό λ©€ν‹°μŠ€λ ˆλ”©μ΄λΌκ³  ν•œλ‹€.

 

λ©€ν‹° μŠ€λ ˆλ”©μ€ ν•˜λ‚˜μ˜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 내에 μ—¬λŸ¬ μž‘μ—…μ„ λ™μ‹œμ— μˆ˜ν–‰ν•˜λŠ” λ©€ν‹° νƒœμŠ€ν‚Ήμ„ κ΅¬ν˜„ν•˜λŠ” 데에 핡심적인 역할을 μˆ˜ν–‰ν•œλ‹€.

 

예λ₯Ό λ“€μ–΄, λ©”μ‹ μ € ν”„λ‘œκ·Έλž¨μ„ μ‚¬μš©ν•  λ•Œ, μƒλŒ€λ°©μ—κ²Œ 보낼 사진을 μ—…λ‘œλ“œν•˜λ©΄μ„œ λ™μ‹œμ— λ©”μ‹œμ§€λ₯Ό 주고받을 수 μžˆλ‹€. 이처럼 λ©”μ‹ μ € ν”„λ‘œκ·Έλž¨μ΄ μ—¬λŸ¬ κ°€μ§€ μž‘μ—…μ„ λ™μ‹œμ— μˆ˜ν–‰ν•˜λ €λ©΄, μž‘μ—…μ„ λ™μ‹œμ— μ‹€ν–‰ν•΄ 쀄 μŠ€λ ˆλ“œκ°€ μΆ”κ°€λ‘œ ν•„μš”ν•˜λ‹€.

 

 

μŠ€λ ˆλ“œμ˜ 생성과 μ‹€ν–‰

 

메인 μŠ€λ ˆλ“œ 외에 λ³„λ„μ˜ μž‘μ—… μŠ€λ ˆλ“œλ₯Ό μ‚¬μš©ν•œλ‹€λŠ” 것은 λ‹€μ‹œ 말해 μž‘μ—… μŠ€λ ˆλ“œκ°€ μˆ˜ν–‰ν•  μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³ , μž‘μ—… μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜μ—¬ μ‹€ν–‰μ‹œν‚€λŠ” 것을 μ˜λ―Έν•œλ‹€.

 

μžλ°”λŠ” 객체지ν–₯ μ–Έμ–΄μ΄λ―€λ‘œ λͺ¨λ“  μžλ°” μ½”λ“œλŠ” 클래슀 μ•ˆμ— μž‘μ„±λ˜λ―€λ‘œ, μŠ€λ ˆλ“œκ°€ μˆ˜ν–‰ν•  μ½”λ“œλ„ 클래슀 내뢀에 μž‘μ„±ν•΄μ£Όμ–΄μ•Ό ν•˜λ©°, run() μ΄λΌλŠ” λ©”μ„œλ“œ 내에 μŠ€λ ˆλ“œκ°€ μ²˜λ¦¬ν•  μž‘μ—…μ„ μž‘μ„±ν•˜λ„λ‘ λ˜μ–΄ μžˆλ‹€.

 

run() λ©”μ„œλ“œλŠ” Runnable μΈν„°νŽ˜μ΄μŠ€μ™€ Thread ν΄λž˜μŠ€μ— μ •μ˜λ˜μ–΄ μžˆλ‹€. λ”°λΌμ„œ, μž‘μ—… μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ν•˜λŠ” 방법은 λ‹€μŒμ˜ 두 κ°€μ§€κ°€ λœλ‹€.

 

  • 첫 번째 방법
    • Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ κ°μ²΄μ—μ„œ run()을 κ΅¬ν˜„ν•˜μ—¬ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³ , μ‹€ν–‰ν•˜λŠ” 방법
  • 두 번째 방법
    • Thread 클래슀λ₯Ό 상속받은 ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ run()을 κ΅¬ν˜„ν•˜μ—¬ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ν•˜λŠ” 방법

 

 

1. Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ κ°μ²΄μ—μ„œ run()을 κ΅¬ν˜„ν•˜μ—¬ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ν•˜λŠ” 방법

public class ThreadExample01 {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new ThreadTask1());
        thread1.start();

        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

class ThreadTask1 implements Runnable{
    public void run(){
        for(int i=0;i<100;i++){
            System.out.print("#");
        }
    }
}
> Task :ThreadExample01.main()
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###@###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###########################################################################################

@와 #이 μ„žμ—¬ μžˆμ–΄ 메인 μŠ€λ ˆλ“œμ™€ μž‘μ—… μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— λ³‘λ ¬λ‘œ μ‹€ν–‰(λ™μ‹œμ— λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰λœλ‹€)λ˜λ©΄μ„œ, 각각 main λ©”μ„œλ“œμ™€ run() λ©”μ„œλ“œμ˜ μ½”λ“œλ₯Ό μ‹€ν–‰μ‹œμΌ°μŒμ„ μ•Œ 수 μžˆλ‹€.

 

 

2. Thread 클래슀λ₯Ό 상속받은 ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ run()을 κ΅¬ν˜„ν•˜μ—¬ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ν•˜λŠ” 방법

package org.example.dev;

public class ThreadExample02 {
    public static void main(String[] args) {
        ThreadTask2 thread2 = new ThreadTask2();

        thread2.start();

        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

class ThreadTask2 extends Thread{
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.print("#");

        }
    }
}
> Task :ThreadExample02.main()
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@################@@@@@@@@@###########@@@@@@##@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#######################################################################

두 번째 방법 μ—­μ‹œ μœ„μ™€ μœ μ‚¬ν•œ κ²°κ³Όλ₯Ό 얻을 수 μžˆλ‹€.

 

μœ„ 두가지 방법 λͺ¨λ‘ μž‘μ—… μŠ€λ ˆλ“œλ₯Ό λ§Œλ“€κ³ , run() λ©”μ„œλ“œμ— μž‘μ„±λœ μ½”λ“œλ₯Ό μ²˜λ¦¬ν•˜λŠ” λ™μΌν•œ λ‚΄λΆ€ λ™μž‘μ„ μˆ˜ν–‰ν•œλ‹€.

 

 

 

읡λͺ… 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ μŠ€λ ˆλ“œ μƒμ„±ν•˜κ³  μ‹€ν–‰ν•˜κΈ°

 

1. Runnable 읡λͺ… κ΅¬ν˜„ 객체λ₯Ό ν™œμš©ν•œ μŠ€λ ˆλ“œ 생성 및 μ‹€ν–‰

package org.example.dev;

public class ThreadExample03 {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.print("#");
                }
            }
        });

        thread1.start();

        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

 

 

2. Thread 읡λͺ… ν•˜μœ„ 객체λ₯Ό ν™œμš©ν•œ μŠ€λ ˆλ“œ 생성 및 μ‹€ν–‰

package org.example.dev;

public class ThreadExample04 {
    public static void main(String[] args) {
        Thread thread2 = new Thread() {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.print("#");
                }
            }
        };

        thread2.start();

        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

 

 

μŠ€λ ˆλ“œ 동기화 문제

 

μ‹±κΈ€ μŠ€λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€μ˜ 경우, 데이터에 단 ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ μ ‘κ·Όν•˜κΈ° λ•Œλ¬Έμ— 문제될 것이 μ—†μœΌλ‚˜, λ©€ν‹° μŠ€λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€μ˜ 경우, 두 μŠ€λ ˆλ“œκ°€ 같은 데이터λ₯Ό κ³΅μœ ν•˜κ²Œ λ˜μ–΄ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.

 

package org.example.thread;

public class ThreadExample05 {
    public static void main(String[] args) {
        Runnable threadTask3 = new ThreadTask3();
        Thread thread3_1 = new Thread(threadTask3);
        Thread thread3_2 = new Thread(threadTask3);

        thread3_1.setName("κΉ€μ½”λ”©");
        thread3_2.setName("λ°•μžλ°”");

        thread3_1.start();
        thread3_2.start();
    }
}

class Account{
    private int balance=1000;

    public int getBalance(){
        return balance;
    }

    public boolean withdraw(int money){
        if(balance>=money){
            try{
                Thread.sleep(1000);
            }catch (Exception error) {}

            balance -= money;

            return true;
        }
        return false;
    }
}

class ThreadTask3 implements Runnable{
    Account account = new Account();

    public void run(){
        while(account.getBalance()>0){
            int money = (int)(Math.random() * 3 + 1) * 100;

            boolean denied = !account.withdraw(money);

            System.out.println(String.format("Withdraw %dβ‚© By %s. Balance : %d %s",
                money, Thread.currentThread().getName(), account.getBalance(), denied ? "-> DENIED" : "")
            );
        }
    }
}

 

> Task :ThreadExample05.main()
Withdraw 100β‚© By λ°•μžλ°”. Balance : 900 
Withdraw 300β‚© By κΉ€μ½”λ”©. Balance : 900 
Withdraw 300β‚© By λ°•μžλ°”. Balance : 600 
Withdraw 100β‚© By κΉ€μ½”λ”©. Balance : 600 
Withdraw 300β‚© By κΉ€μ½”λ”©. Balance : 300 
Withdraw 100β‚© By λ°•μžλ°”. Balance : 200 
Withdraw 300β‚© By κΉ€μ½”λ”©. Balance : -100 
Withdraw 200β‚© By λ°•μžλ°”. Balance : -300

좜λ ₯ κ²°κ³Όλ₯Ό 보면, 인좜금과 μž”μ•‘μ΄ μ œλŒ€λ‘œ 좜λ ₯λ˜μ§€ μ•Šκ³  μžˆμŒμ„ μ•Œ 수 μžˆλ‹€.

 

μ΄λŠ” 두 μŠ€λ ˆλ“œ 간에 객체가 곡유되기 λ•Œλ¬Έμ— λ°œμƒν•˜λŠ” 였λ₯˜λ‘œ, 값이 μ™œ μ΄λ ‡κ²Œ 좜λ ₯λ˜μ—ˆλŠ”μ§€ μΆ”μΈ‘ν•˜κΈ°κ°€ μ–΄λ ΅λ‹€.

 

λ˜ν•œ, withdraw()μ—μ„œ μž”μ•‘μ΄ 인좜되고자 ν•˜λŠ” κΈˆμ•‘λ³΄λ‹€ λ§Žμ€ κ²½μš°μ—λ§Œ 인좜이 κ°€λŠ₯ν•˜λ„λ‘ μ½”λ“œλ₯Ό μž‘μ„±ν•΄ λ‘μ—ˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³  (if(balance>= money) ~), 마치 쑰건문이 λ¬΄μ‹œλœ κ²ƒμ²˜λŸΌ 음수의 μž”μ•‘μ΄ λ°œμƒν•˜λŠ” 것을 확인할 수 μžˆλ‹€.

 

μ—¬κΈ°μ—μ„œ 음수의 μž”μ•‘μ΄ λ°œμƒν•˜λŠ” μ΄μœ λŠ”, 두 μŠ€λ ˆλ“œκ°€ ν•˜λ‚˜μ˜ Account객체λ₯Ό κ³΅μœ ν•˜λŠ” μƒν™©μ—μ„œ, ν•œ μŠ€λ ˆλ“œκ°€ if 문의 쑰건식을 true둜 ν‰κ°€ν•˜μ—¬ if 문의 μ‹€ν–‰λΆ€λ‘œ μ½”λ“œμ˜ 흐름이 μ΄λ™ν•˜λŠ” μ‹œμ μ— λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ 끼어듀어 balanceλ₯Ό μΈμΆœν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

 

그리고, μ•Œ 수 μ—†λŠ” 원인에 μ˜ν•΄ μΈμΆœμ— μ‹€νŒ¨ν•œ κ²½μš°μ— --> DENIEDκ°€ μ œλŒ€λ‘œ 좜λ ₯λ˜μ§€ μ•ŠλŠ” λ¬Έμ œλ„ λ°œμƒν•œλ‹€.

 

μ΄λŸ¬ν•œ 상황이 λ°œμƒν•˜μ§€ μ•Šκ²Œ ν•˜λŠ” 것을 μŠ€λ ˆλ“œ 동기화라고 ν•œλ‹€.

 

μŠ€λ ˆλ“œ 동기화
πŸ‘‰λ‹€μˆ˜μ˜ μŠ€λ ˆλ“œκ°€ ν•œ λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•˜λ € ν•  λ•Œ, μ‚¬μš©ν•˜λ €λŠ” μŠ€λ ˆλ“œλ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ μŠ€λ ˆλ“œλ“€μ€ λ¦¬μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•˜μ§€ λͺ»ν•˜λ„둝 λ§‰λŠ” 것.

 

 

 

μž„κ³„ μ˜μ—­(Critical section)κ³Ό 락(Lock)

 

μž„κ³„ μ˜μ—­μ€ μ˜€λ‘œμ§€ ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλŠ” μ½”λ“œ μ˜μ—­μ„ μ˜λ―Έν•˜λ©°, 락은 μž„κ³„ μ˜μ—­μ„ ν¬ν•¨ν•˜κ³  μžˆλŠ” 객체에 μ ‘κ·Όν•  수 μžˆλŠ” κΆŒν•œμ„ μ˜λ―Έν•œλ‹€.

 

즉, μž„κ³„ μ˜μ—­μœΌλ‘œ μ„€μ •λœ 객체가 λ‹€λ₯Έ μŠ€λ ˆλ“œμ— μ˜ν•΄ μž‘μ—…μ΄ 이루어지고 μžˆμ§€ μ•Šμ„ λ•Œ, μž„μ˜μ˜ μŠ€λ ˆλ“œ AλŠ” ν•΄λ‹Ή 객체에 λŒ€ν•œ 락을 νšλ“ν•˜μ—¬ μž„κ³„ μ˜μ—­ λ‚΄μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ‹€.

 

μ΄λ•Œ, μŠ€λ ˆλ“œ Aκ°€ μž„κ³„ μ˜μ—­ λ‚΄μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ 쀑일 λ•Œμ—λŠ” λ‹€λ₯Έ μŠ€λ ˆλ“œλ“€μ€ 락이 μ—†μœΌλ―€λ‘œ 이 객체의 μž„κ³„ μ˜μ—­ λ‚΄μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μ—†λ‹€.

 

μž μ‹œ λ’€, μŠ€λ ˆλ“œ Aκ°€ μž„κ³„ μ˜μ—­ λ‚΄μ˜ μ½”λ“œλ₯Ό λͺ¨λ‘ μ‹€ν–‰ν•˜λ©΄ 락을 λ°˜λ‚©ν•˜κ³ , μ΄λ•Œ λΆ€ν„° λ‹€λ₯Έ μŠ€λ ˆλ“œ 쀑 ν•˜λ‚˜κ°€ 락을 νšλ“ν•˜μ—¬ μž„κ³„ μ˜μ—­ λ‚΄μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ‹€.

 

μœ„ μ˜ˆμ œμ—μ„œ μš°λ¦¬μ—κ²Œ ν•„μš”ν–ˆλ˜ 것은 두 μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μ‹€ν–‰ν•˜λ©΄ μ•ˆλ˜λŠ” μ˜μ—­μ„ μ„€μ •ν•˜λŠ” 것이닀. 즉, withdraw() λ©”μ„œλ“œλ₯Ό 두 μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μ ‘κ·Όν•˜μ§€ λͺ»ν•˜λ„둝 ν•΄μ•Ό ν•œλ‹€.

 

πŸ’‘withdraw() λ©”μ„œλ“œλ₯Ό μž„κ³„ μ˜μ—­μœΌλ‘œ μ„€μ •ν•œλ‹€.

 

νŠΉμ • μ½”λ“œ ꡬ간을 μž„κ³„ μ˜μ—­μœΌλ‘œ μ„€μ •ν•  λ•ŒλŠ” synchronized λΌλŠ” ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

 

 

1. λ©”μ„œλ“œ 전체λ₯Ό μž„κ³„ μ˜μ—­μœΌλ‘œ μ§€μ •ν•˜κΈ°

public synchronized boolean withdraw(int money){
        if(balance>=money){
            try{
                Thread.sleep(1000);
            }catch (Exception error) {}

            balance -= money;

            return true;
        }
        return false;
    }

μ΄λ ‡κ²Œ λ©”μ„œλ“œ 전체λ₯Ό μž„κ³„ μ˜μ—­μœΌλ‘œ μ§€μ •ν•˜λ©΄ λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜μ—ˆμ„ λ•Œ, λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•  μŠ€λ ˆλ“œλŠ” λ©”μ„œλ“œκ°€ ν¬ν•¨λœ 객체의 락을 μ–»λŠ”λ‹€.

즉, withdraw()κ°€ 호좜되면, withdraw()λ₯Ό μ‹€ν–‰ν•˜λŠ” μŠ€λ ˆλ“œλŠ” withdraw()κ°€ ν¬ν•¨λœ 객체의 락을 μ–»μœΌλ©°, ν•΄λ‹Ή μŠ€λ ˆλ“œκ°€ 락을 λ°˜λ‚©ν•˜κΈ° 이전에 λ‹€λ₯Έ μŠ€λ ˆλ“œλŠ” ν•΄λ‹Ή λ©”μ„œλ“œμ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜μ§€ λͺ»ν•˜κ²Œ λœλ‹€.

 

 

2. νŠΉμ •ν•œ μ˜μ—­μ„ μž„κ³„ μ˜μ—­μœΌλ‘œ μ§€μ •ν•˜κΈ°

public synchronized boolean withdraw(int money){
        synchronized (this){
            if(balance>=money){
                try{
                    Thread.sleep(1000);
                }catch (Exception error) {}

                balance -= money;

                return true;
            }
            return false;
        }
    }

 

νŠΉμ • μ˜μ—­μ„ μž„κ³„ μ˜μ—­μœΌλ‘œ μ§€μ •ν•˜λ €λ©΄ μœ„μ™€ 같이 synchronized ν‚€μ›Œλ“œμ™€ ν•¨κ»˜ μ†Œκ΄„ν˜Έ μ•ˆμ— ν•΄λ‹Ή μ˜μ—­μ΄ ν¬ν•¨λœ 객체의 μ°Έμ‘°λ₯Ό λ„£κ³ , μ€‘κ΄„ν˜Έ({})둜 블둝을 μ—΄μ–΄, 블둝 내에 μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄ λœλ‹€.

 

이 κ²½μš°μ—λ„ λ§ˆμ°¬κ°€μ§€λ‘œ, μž„κ³„ μ˜μ—­μœΌλ‘œ μ„€μ •ν•œ λΈ”λ‘μ˜ μ½”λ“œλ‘œ μ½”λ“œ μ‹€ν–‰ 흐름이 μ§„μž…ν•  λ•Œ, ν•΄λ‹Ή μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ³  μžˆλŠ” μŠ€λ ˆλ“œκ°€ this에 ν•΄λ‹Ήν•˜λŠ” 객체의 락을 μ–»κ³ , λ°°νƒ€μ μœΌλ‘œ μž„κ³„ μ˜μ—­ λ‚΄μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œλ‹€.

 

1번 처럼 λ©”μ„œλ“œ 전체에 락을 κ±°λŠ” 것보닀 synchronized λΈ”λ‘μœΌλ‘œ μž„κ³„ μ˜μ—­μ„ μ΅œμ†Œν™”ν•΄ 효율적인 ν”„λ‘œκ·Έλž¨μ΄ λ˜λ„λ‘ ν•˜λŠ” 것이 λ°”λžŒμ§ν•˜λ‹€.

 

 

Thread Safe

 

'μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μ–΄λ–€ λ¦¬μ†ŒμŠ€λ₯Ό 접근해도 ν”„λ‘œκ·Έλž¨μ΄ μ•ˆμ •μ μœΌλ‘œ λ™μž‘ν•˜λŠ” 것'을 λ§ν•œλ‹€.

 

즉, Thread Safeλ₯Ό 보μž₯ν•˜κΈ° μœ„ν•œ 방법 쀑 ν•˜λ‚˜κ°€ μŠ€λ ˆλ“œ 동기화이며, Thread SafeλŠ” Immutable Objectλ₯Ό μƒμ„±ν•΄μ„œλ„ 보μž₯이 κ°€λŠ₯ν•˜λ‹€.

 

 

Immutable Objectλ₯Ό μ‚¬μš©ν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™λ‹€.