이하 구디아카데미 김지훈 강사님의 수업자료와 강의 내용 정리, 실습한 내용을 정리함
신나는🤣 월요일 시작!
Multi Thread
정의
Thread
- Thread 는 어떤 program 을 실행하게 해주는 원동력이다.
- 대표적으로 main(String[] args) 는 thread 를 동작하게 해주는 method 이다.
Process 와 Thread 의 차이
- Process 는 프로그램이 돌고 있는 단위
- Process 는 1 개 이상의 thread 로 구성되어 있다.
- 가장 대표적인 차이는 바로 memory Share 여부이다.
- Process 간에는 memory Share 가 되지 않는다.
- Thread 간에는 memory Share 가 된다.
- ex) Excel(Process) Word(process) 간에는 서로 상태가 공유되지 않는다.
Word(process) 내의 글 작성 기능 (Thread) 과 자동완성 기능 (Thread) 은 서로 상태를 알고 있다.
multi thread
- 그동안 사용한 main method 는 main Thread 를 생성한다.
- 이 main Thread 는 자신을 위해 일할 work Thread 를 생성할 수 있다.
- 이것을 multi thread 라고 한다.
요약
- Thread 는 program 을 움직이는 원동력이다.
- Process 는 하나 이상의 Thread 로 되어 있다.
- Main Thread 로 여러 개의 work thread 를 만들 수 있다.
Thread 생성 방법
- Thread 생성 방법은 Runnable interface 구현과 Thread class 상속 방법이 있다.
- 두 방법 모두 익명 (Anonymous) 객체를 활용할 수도 있다.
- MainThead 와 WorkThead 가 각자 일을 수행하기 때문에 순서를 예측하기 쉽지 않다.
implements Runnable(Runnable 구현)
1. Runnable 을 구현받아온 WorkThread 를 생성
2. run 메서드를 오버라이드 해와서 for 문 1부터 5까지 실행
3. 그 후 0.5 초 쉬게 한다.
1. 워크 스레드 생성한 후
2. 워크 스레드를 Runnable 형식의 run 이라는 객체로 객체화함
3. Thread 클래스에 run 을 넣어 thread 로 객체화
4. thread 를 실행시켜 줌
5. 1~4까지 for 문을 실행시키고 thread 를 0.5초간 쉬게 함
익명 객체로 구현
extends Thread
익명 객체로 구현
Thread Name
- Thread 가 여러 개다 보면 각각의 이름이 필요하다.
- 이름을 지정하지 않으면 Thread n(0 부터 시작 ) 형태의 이름이 자동 지정 된다
- 다른 이름을 지정 하고 싶다면 setName () 을 사용하면 된다.
Thread 제어
- 여러 Thread 를 실행하다 보면 순서가 제멋대로인 것을 볼 수 있다.
- Thread 는 여러 일을 동시에 주기적으로 처리해 줄 수 있으나 제어가 어렵다.
- Thread 는 Round Robin 방식을 사용하기 때문이다.
- 빨리 처리한 녀석이 다음 일을 받는 방식이므로 먼저 시작했다고 먼저 끝나지 않는다.
Synchronized
- Thread 는 memory 를 공유하기 때문에 객체 간의 데이터 간섭이 일어나기도 한다.
- 즉, 내가 사용하는 데이터를 누군가 사용하여 값이 바뀔 수도 있다는 뜻이다.
- 이런 불상사를 대비하기 위해 우리는 자리를 비울 때 컴퓨터를 잠근다.
- 이것을 스레드에서는 동기화 (Synchronize) 라고 한다.
- 동기화란 내 작업이 다 끝나기 전에는 아무도 접근하지 못하게 하는 것이다.
예) Vector, HashTable
-
User1 Thread 가 점수를 500 점으로 기록하고 잠시 자리를 비운다. score =500
-
User2 Thread 가 그 사이 점수를 100 점으로 만들어 놓았다. score = 100
-
User1 Thread 가 돌아와 보니 점수가 100 점이 되어 있다. score = 100
-
Thread Priority 따라 500,500 등의 비정상적인 결과가 나타날 수도 있다.
-
Synchronized 하는 방법은 크게 두 가지가 있다.
-
Synchronized method 를 사용하는 방법과
-
Synchronized block 을 사용하는 방법이다.
synchronized test
console
요약
- Thread 는 round robin 방식으로 먼저 시작한 일이 먼저 끝나지 않는다.
- 그런 특성 때문에 thread 를 제어하기 위한 방법들이 필요하다.
- 또한 thread 는 memory 를 공유하므로 간섭 효과가 생긴다.
- 이를 막기 위해 synchronized 를 사용한다.
Thread State
-
Thread 는 생성부터 종료까지의 상태 값이 있다.
-
우리는 getState() 를 통해 현재 상태를 알 수 있다.
-
New, Runnable, Terminated 상태 값 정도가 주로 쓰인다.
-
Work thread 에게 일을 시키고 main thread 가 상태를 확인하기
Thread Control
- Thread 는 매우 유용한 기능이지만 예상대로 움직이지 않는다.
- 그래서 Thread Control 을 위한 method 들이 존재한다.
sleep()
- Sleep 은 주어진 milliseconds 동안 thread 를 일시정지 시킨다.
- Thread.sleep (1000) 형식으로 사용한다.
yield()
- Yield 는 특정 스레드에게 제어권을 양보한다. => 너도 한번 할 기회를 줄게.
- Thread.yield () 형식으로 사용한다.
join()
- Join 은 다른 thread 의 종료를 기다린 후에 실행할 때 사용한다.
- Join 을 사용할 때와 사용하지 않을 때 비교
wait(), notify(), notifyAll()
- wait() 은 내가 쉬는 것이고, notify() 는 누군가를 깨우는 것이다.
- 아래의 상황은 wait 와 notify 를 실행하는 과정이다.
- notify() 는 스레드 중 하나(즉, 랜덤 스레드)를 깨운다.
- wait() 와 notify() 를 이용하여 공동 데이터에 하나의 스레드만 접근하도록 만들기
- wait(), notify(), notifyAll() 호출은 synchronized 안에서 해야 한다.
요약
- Thread 제어를 위한 방법은 여러가지가 있다.
- sleep() 은 스스로가 정해진 시간만큼 쉬는 것이다.
- yeild () 는 상대에게 실행할 기회를 주는 것이다.
- join() 은 특정 스레드의 종료를 기다리는 것이다.
- wait() 는 누군가가 notify() 해줄 때까지 쉬는 것이다.
Stop flag, interrupt()
-
기본적으로 thread 는 run() 의 실행 내용이 모두 실행되면 종료된다.
-
무한 반복문으로 이루어진 경우는 강제 종료가 필요하다.
-
이때 stop() 을 사용할 수 있으나 현재는 사용중지를 권고하고 있다.
-
Stop flag / Forced interrupt 강제 인터럭트
Demon Thread
- Demon Thread 는 main thread 작업을 돕는 보조적인 역할을 수행한다.
- Work Thread 와 마찬가지로 main thread 에 의해서 생성된다.
- 다만 life cycle 의 차이가 있다.
요약
- Thread 를 정지시키는 방법은 여러 가지가 있다 .(stop() 사용 금지)
- Demon thread 는 main thread 와 life cycle 을 같이 한다.
- 프로세스와 쓰레드 중 메모리를 공유하는 것이 무엇인가요?
- multi thread란 무엇인가 말해 보세요.
- 자신을 위해 일할 work Thread 를 생성할 수 있다. 이것을 multi thread 라고 한다.
- thread 생성방법 두 가지는 무엇이 있는지 말해 보세요.
- Runnable interface 구현 / Thread class 상속
- Thread 의 장점과 단점은 어떤 것인가요?
- 여러 일을 동시에 주기적으로 처리해 줄 수 있다.
- 제어가 어렵다.
- Thread가 메모리를 공유하기 때문에 생기는 문제는 무엇이며 그 문제를 방지하기 위해 어떤 방법을 사용할 수 있나요?
- 객체 간의 데이터 간섭이 일어나기도 해서 내가 사용하는 데이터를 누군가 사용하여 값이 바뀔 수도 있다.
- 내 작업이 다 끝나기 전에는 아무도 접근할 수 없도록 동기화(Synchronize)를 한다.
- Synchronized를 하는 방법 두 가지에는 무엇이 있나요? 두 방법의 차이점은?
- Synchronized method 사용 / Synchronized block 사용
- mothod 를 사용하면 밖에서 줄을 섰다가 들어오고, block 을 사용하면 안에서 줄을 섰다가 들어옴
-
Thread 를 제어하기가 어려운 이유가 Thread가 어떤 방식을 사용하기 때문인지와, 그 방식의 동작 방식을 간단하게 설명하세요.
Round Robin 방식을 사용한다. 빨리 처리한 녀석이 다음 일을 받는 방식이므로 먼저 시작했다고 먼저 끝나지 않는다.
-
Thread의 상태중 NEW / RUNNABLE / TERMINATED 가 각각 어떤 상태인지 설명하세요.
- NEW : 스레드 객체 생성, start() 호출 전
- RUNNABLE : 실행 상태로 언제든지 이동할 수 있는 상태
- TERMINATED : 실행을 마친 상태
- 쓰레드를 한번씩 번갈아가면서 실행시킬때 yield가 적합하지 않은 이유를 설명하세요.
- 차례대로 실행하는 것이 아니라 특정 스레드에게 한번 제어권을 넘겼다가 응답이 없으면 바로 원 스레드가 실행하기 때문에
- Thread 를 Control 하기 위한 method 중 세 가지를 말해 보세요.
- sleep() / yield() / join()
- wait 와 notyfy 의 실행 순서는? 그리고 notify 와 nothfiAll 의 차이는 무엇인가요?
- notyfy 후 > wait
- notify 는 일시정지 상태 중인 스레드 중 하나를 실행대기 상태로 바꾸고, notifyAll 은 일시 정지된 모든 스레드를 실행대기 상태로 만든다.
- Thread control method 중 join 을 사용하면 좋은 점은 무엇인가요?
- join 을 사용하지 않을 시에는 실행하는 시간에 따라 값을 다르게 설정해야 하는데, 너무 짧게 잡으면 끝나기 전에 아래 내용이 수행되고 너무 길게 잡으면 낭비되는 시간이 생긴다.
- 그에 비해 join 은 work 스레드가 수행 후 당도하면 그때 이후의 내용을 실행하는 블로킹 방식이다.
- Stop flag 와 interrupt 의 차이와, interrupt 를 활용하는 두 가지 방법에는 어떤 것이 있나요?
- stop Flag 는 멈추는 조건을 설정하여 루프를 빠져나가게 하고,
- interrupt 는 Exception을 통해 루프를 빠져나가게 한다.
- interrupt 로 정지시키는 방법과 interrupted 로 발생했는지 확인하여 정지시키는 방법이 있다.
- Demon Thread 와 Work Thread 의 차이는 무엇이 있나요?
- Demon Thread 는 Work Thread 와 달리 Main Thread 가 끝나면 같이 종료된다.