쓰레드 강의노트

□ Thread and Synchronization


 ▷ 쓰레드의 이해와 쓰레드의 생성

  - 쓰레드의 이해와 쓰레드의 생성 방법

  - 쓰레드를 생성하는 2가지 방법


 ▷ 쓰레드의 동기화

  - 쓰레드의 메모리 접근 방식과 그에 따른 문제점

  - 동일한 메모리 공간에 접근하는 것이 왜 문제가 되는가?

  - 동기화(Synchronization) 메소드

  - 동기화(Synchronization) 블록


 ▷ 쓰레드를 생성하는 더 좋은 방법

  - 지금 소개하는 이 방법으로 쓰레드를 생성하고 활용하자.

  - Callable & Future

  - synchronized를 대신하는 ReentrantLock

  - 컬렉션 인스턴스 동기화




쓰레드(Thread)

 : 프로세스 내에서 또 다른 실행의 흐름을 형성하는 주체


 실행 중인 프로그램을 가리켜 프로세스라고 한다.

main method를 실행하기 위한 쓰레드가 실행되어 왔었다.

하나의 프로세스 안에 둘 이상의 쓰레드가 존재하는 걸 가리켜 멀티 쓰레드라고 한다.

main 메소드는 자동적으로 실행이 되지만, 나머지는 사용자가 직접 실행시켜줘야 한다.

# 한번 실행이 종료된 쓰레드는 다시 실행할 수 없다 ==> 하나의 쓰레드에 한 번의 start() 호출.


# 멀티 쓰레드 프로그래밍 할 때 쓰레드의 실행 흐름을 예측하려고 하지 말고,  끝난다는 게 중요

쓰레드의 실행순서는 OS의 스케쥴러가 작성한 스케쥴에 의해 결정된다.


ㆍ 쓰레드를 생성하는 2가지 방법


 1. Inheritance

  ① Thread를 상속하는 클래스의 정의와 인스턴스 생성

  ② start 메소드 호출


 2. Runnable Interface (★ 람다식 기반이라 더 많이 쓰임)

  ① Runnable을 구현한 인스턴스 생성

  ② Thread 인스턴스 생성

  ③ start 메소드 호출



3. start() run() 설명

4. 싱글쓰레드, 멀티쓰레드

5. 쓰레드의 우선순위


동기화(Synchronization)

 : 실행


동기화가 왜 필요한가? -> 쓰레드가 갖는 문제점이 무엇인가? -> 그 문제를 해결하는 방법 이 순으로 접근




ㆍ 기본이 되는 2가지 동기화 방법


 1. Synchronized Methods

  ㆍ 개념 : 이 메소드를 실행하는 중간에 다른 쓰레드는 들어오지 마라!

  ㆍ 단점 : 메소드 전체에 동기화를 걸어아 한다.


 2Synchronized Blocks

  ㆍ 개념 : 쓰레드가 { } 안에 들어오면 중간에 다른 쓰레드가 접근하는 것을 막겠다!



ㆍ 문제점


ㆍ 해결 방안


쓰레드 풀(Thread Pool)

 : 쓰레드 풀 안에 미리 제한된 수의 쓰레드를 생성해 두고 이를 재활용하는 기술




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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package atm;
 
class ATM implements Runnable {
 
    private long depositeMoney = 10000;
    
    public void run() {
//        synchronized (this) {
            for(int i = 0; i<10; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                if (getDepositeMoney() <= 0)
                    break;
                withDraw(1000);
            }
//        }
    }
 
    public void withDraw(long howMuch) {
        
        if (getDepositeMoney() > 0) {
            depositeMoney -= howMuch;
            
            System.out.print(Thread.currentThread().getName() + ", ");
            System.out.printf("잔액 : %,d 원 %n", getDepositeMoney());
        } else {
            System.out.print(Thread.currentThread().getName() + ", ");
            System.out.println("잔액이 부족합니다.");
        }
    }
    
    public long getDepositeMoney() {
        return depositeMoney;
    }
}
 
public class SychronizedEx {
 
    public static void main(String[] args) {
        ATM atm = new ATM();
        Thread mother = new Thread(atm, "mother");
        Thread son = new Thread(atm, "son");
        
        mother.start();
        son.start();
    }
    
}
cs

실행시켜보자 무슨 문제가 있을까?
mother가 잠깐 block 되고

동기화를 처리하지 않았을 때 이러한 문제점이 생긴다
이 문제를 해결하기 위해 주석 부분을 해제하고 다시 실행해보자

1000원씩 쓰는건 됐다. But, 엄마가 독점해버림
아들은 기아 상태가 되버렸다.


댓글(0)

Designed by JB FACTORY