Thread -
- 쓰레드는 일꾼이다.
- 쓰레드는 하는 일이 정해져 있어야 한다 run() 메서드로!
- run() 메서드는 우리가 만드는 메서드가 아니다.
- run() 메서드는 누가 만들어 놓은 메서드를 다시 사용하는 것이다.
- @Override run( ) 해서 지정해 주어야 한다~!
- 쓰레드를 만드려고 하면 run() 메서드를 가진 부모가 일단 있어야 한다.
- 이 부모의 형태가 2가지이다. 클래스이거나 인터페이스이거나
- 클래스는 extends / 인터페이스는 implements 해주어야 한다.
쓰레드 생성방식 3가지
- extends
- implements
- lambda
쓰레드 생성 방법이 왜 종류가 여러 개 인가요?
- java는 단일 상속만 가능하므로
- IF ) 이미 Person 상속받은 Man을 Thread 로 만들어 주려면?
- 다중 상속 불가! implement만 가능
- 보통 implements 많이 사용한다. extends로 박아놓으면 다른 부모 사용 못하니까.
- 람다는 왜 나왔냐??
- 간단하게 말하면 implemnets / extends 해서 하는 작업을 람다식으로 간단히 사용하기 위해서
- 쓰레드 하나한테 출력문 하나 실행하는 일 시킬 건데 그거 하려고
- 인터페이스 구현한 클래스 만들고 다시 쓰레드 만들고 하기 번거롭고 힘들다..
실습하면서 알아보자!
실습
- 쓰레드 생성하기
- 쓰레드 사용하기
쓰레드 생성하기 1번째 – extends Thread
1. extends Thread
- Thread 클래스 안에 run() 메서드 있다.
- 이제 MyThread를 실행하면 우리가 만들어 놓은 run() 실행된다.
2. 메인에서 쓰레드 생성해주기 - new MyThread();
- 메인에서 객체 생성 실행 테스트
- 왜 run()이 아니라 - start(); 메서드로 사용하나요?
- run()으로 사용해봤더니 둘 다 main메서드가 작업해준다.
- start() 라는 것은 - 새로운 객체(쓰레드)를 만들어 주고-> run() 메서드를 실행해주는 의미
- 메인 메서드 안에서 그냥 run() 해버리면 – 메인쓰레드한테 그냥 run()하라고 명령한 의미
+@ 메인 쓰레드의 역할
- 메인쓰레드가 쭉 가면서 t1 쓰레드 생성해주고 다시 돌아와서 나머지 일 실행
- --- 나의 이해
- 메인 쓰레드가 객체를 생성하고 접근해서 메서드를 실행하고 돌아오고 하는 거였는데,
- 쓰레드.start() 의 경우에는 메인 쓰레드가 객체를 찾아가서 그 안에 run()까지 실행하는 게 아니라
- 객체(쓰레드)를 만들어 주기만 하고 돌아오고, 그 객체(쓰레드)가 알아서 run() 실행하게 놔두는 거라고 이해
객체에 대해서 새로운 정의
- 객체 스스로 일을 한다. 이 객체가 이거 한다 이거 한다 이런 식으로 생각해왔다.
- BUT 사실은 객체가 스스로 일을 하는 것이 아니다.
- 객체도 보면 데이터 덩어리이다.( 데이터가 있고 메서드가 있는)
int x = new Hello().hello();
- 객체를 생성하고 / 접근해서 / hello() 메서드 실행 / 변수 x에 담는다.
- 여기서 접근해서! 이 부분!에
- 쓰레드가! 일을 다 한다.
- 접근해서 – 메서드 실행하고 그 값을 – 변수 x에 담아주는 일을 한다.
- 객체가 한 일은? 데이터 제공?
MyQuestion -
- 쓰레드는 시작만 해주면 자기 할 일 다 끝내면 종료는 자동으로 되는 건가요?
- 작업이 끝나면 쓰레드가 없어지는 건가요?
- -> 맞습니다, 쓰레드가 죽은 상태가 된다.
- 쓰레드.isAlice(); 로 확인 가능 ( 너무 빠르게 확인하면 살아있다고 나올 수도 있다. )
쓰레드 생성하기 2번째 – implement Runnable
1. implement Runnable
- implements Runnable – 추상 메서드 구현하라고 컴파일 에러 난다.
- @Override run(){}
2. new MyThread(My Runner());
## Check Point
- 러너는 쓰레드 만든 것처럼 바로 사용할 수 없고.
- 어떤 쓰레드를 생성해주고 –
- 그 안쪽에 인자 값으로 러너를 전달하는 방식으로 사용
- new Thread(); 만들면 – 비어있는 상태다.
- run()을 오버라이드 해줘야 하는데 == run() 메서드를 채워주어야 하는데
- 현재 우리가 run() 오버라이드 한 방식은 – MyRunner()로 오버라이드 한 상태
- MyRunner 객체로 전달 가능하다.
- 가능한 이유는 MyRunner 는 - Runnable이라는 interface를 가지고 있기 때문에
- ( Runnable을 구현한 클래스 객체는 가능하다 )
- 함수 지향적 프로그램
+@ FunctionalInterface
- Runnable 이란 인터페이스는 –> run() 이라는 메서드 단 하나만을 보유한 인터페이스
- 이런 인터페이스를 Functional Interface 라고한다.!
- Functional Method
나온 이유?
- java는 타입 언어 / python, javascript 이런 애들은 논 타입 언어
- 합의점을 찾는 방향으로 생태계 변화 중인데 그 역할
- – 다른 언어의 장점을 사용할 수 있는 방법으로!
- 함수형 프로그래밍 – 자바에서는 변수에 함수를 넣을 방법이 없었다.
- 그런데 객체를 넣는 것은 가능하네?
- 이 객체를 interface로 만들어서 하자.
- 대신 이 interface는 메소드 1개만 가지도록 해주자. - 이것이 functional interface
쓰레드 생성하기 3번째 – 람다식
- 변수에 함수를 넣어주기 위해선
- implements Runnable해준 객체나 extends Thread해준 객체를 생성해서 넣어주어야 하는데
- 이런 방법이 너무 번거롭고 힘들다.
- 이 작업을 좀 더 쉽게 해 주기 위해 - 람다식이 나왔다.
위에서 했던 객체를 생성해서 넣어주는 작업은
메소드(입력값, 할 일, 출력 값) 하나를 채워주기 위한 것인데 너무 번거롭고 힘들다.
이런 작업을 편리하고, 수월하게 해주자 하는 것이 람다식 (입력값, 할 일, 출력 값)을 채워주는 것
1. new Thread(); 생성 -
- 이 상태는 현재 t3 쓰레드 안에는 비어있는 상태
- run() 메서드를 채워주어야 한다.
- 지금까지 extends / implements 해서 객체를 넣어 준 이유는?
- run() 메서드를 채워 주기 위해서
- 그럼 굳이 객체로 채워주지 말고 메서드를 넣어주자
2. 람다식으로 run() 메서드 채워주기
2-1 명령어가 1개일 때 : ()->()
- { } 생략 가능
- ; 생략 가능
2-2 명령어가 2개일 때 : ()->{();}
- { } 필요
- ; 필요 ( 명령어 하나하나마다 )
여기까지 쓰레드 생성하는 방법 3가지 알아봤고
쓰레드 사용하는 방법 중 start 하나 알아보았다.
쓰레드 사용하는 방법 더 알아보자!
쓰레드에서 알아야 할 키워드
[ start, run, sleep, interrupt, wait, notify, notifyAll, state, join, yield, daemon, group, pool, priority ]
start , run
- 쓰레드.start() 하면 run()메서드 실행
sleep
- 쓰레드 잠재움, 대기열로 일정 시간 동안 보낸 후 다시 실행하게 해 준다.
stop( xxx )
- 쓰레드 종료 ( 이제 안씀 - flag로 흐름 제어 )
- 쓰레드 자원 낭비와 비정상 종료 에러로 사용 안 하는 추세
- isFlag = true || false 해서 무한 반복문 제어해준다.
interrupt
- 쓰레드를 방해한다.
- 쓰레드가 예외 던지고 종료한다.
- 사용 중에 방해를 받으면 그 즉시가 아니라, wait상태로 바뀌는 순간 - 예외처리로 던져버리고 종료
- 한 사이클 동작하고 그만했으면 좋겠다는 상황에서 주로 사용
wait
- sleep이랑 비슷
- wait() 메서드를 만나면 대기 상태로 간다.
- 몇 초 동안 대기 상태로 보내는 초 지정도 가능.( 다만 sleep()와 달리 그 시간을 다 채우지 않아도 누가 깨워주면 다시 가서 수행 )
- 동기화 관련 차이가 있음( 모니터 획득, lock 여부 등)
notify, notifyAll
- 깨우다 - 대기실에 wait 하는 애들 다시 일하라고 명령함
- 대기 상태에 있는 어떤 쓰레드를 깨워주는 역할을 한다.
- 객체 안에는 대기열이 있다.
- 쓰레드가 객체에 와서 작업을 하다가 메서드 안에서 wait()을 만나게 됐다?
- 이 메서드를 대기열로 보낸다. t1 대기열로
- 이상태에서 t2가 와서 notify() 하게 되면 대기열에 있는 쓰레드 중 하나 깨워준다(어떤것일지는 모른다)
- 그래서 notifyAll로 대기실에 있는 모든 애들 한 번에 깨워줄 수도 있다.
state
- 쓰레드의 상태( 생성 , 실행 , 대기 , 종료 )
join
- 다른 쓰레드 기다려 줌
- t2의 결과 값이 필요한 경우에 사용
yield
- 다른 쓰레드한테 컴퓨터 자원 cpu 쓸 수 있게 양보하다.
- core가 1개다? thread 1개밖에 못돌림.( 실제로는 아니지만 예시로 )
- S/W 잘 깔아봤자 H/W가 못 받쳐주면 일 못함.
- 예시) Thread 100개가 있다. / 코어가 16개 있다.
- 1번부터 16번 쓰레드까지는 할 일을 하는데 나머지는 일을 못한다.
- 그럴 때 다른 쓰레드가 1번 쓰레드한테 양보하라고 yield하면 쓰던 코어 반납하고 내려놓는다.
- 양보해봤자 우선순위가 낮은 애한테는 양보 안됨. 꼭 그렇지도 않음..
- 요즘은 yield() 사용 잘 안 함. 내가 원하는 대로 통제하기도 어려움
daemon
- 다른 쓰레드에 종속되는 쓰레드
- 부노 쓰레드가 종료되면 데몬 쓰레드도 종료
- 처음부터 데몬쓰레드로 만들어 주어야 함
- 예시) ctrl + z , ctrl + y 이런거 사용하는데 // 이런 기능들은 메인 기능들이 아니다.
- 이런 부가적인 기능을 수행하는 쓰레드 t1은 main쓰레드가 있어야 존재할 수 있다.
- main 없는데 ctrl + z , ctrl + y 기능? 필요 없다. 존재할 이유 없다.
- 이럴 상황일 때 처음부터 daemon 쓰레드로 만들어 준다.
group
- 쓰레드를 그룹단위로 묶어서 관리하는
pool
- 쓰레드를 매번 만들어서 사용하고 하는 것이 아니라.
- 만들어 놓고 가져다 사용하는
priority
- 쓰레드 우선순위 지정 ( 우선순위대로 실행 안 되는 경우도 많다 )
진도 +
최근 트렌드는 병렬 프로그래밍을 좋아하는 추세
- H/W의 발전에 따라서 - H/W가 받쳐줘서 – 동시에 많은 쓰레드를 사용 가능해져서
- 병렬 프로그램 사용 안 하면 손해다. / core가 100개가 있는데 10개만 사용하면 자원 손해.
- 이런 병렬 프로그래밍 작업이 어려운데 – 함수로 만들어놨다.
- 함수만 호출하면 병렬 프로그램으로 만들어줌 – 이거와 연관되어있는 것이 – 함수형 프로그래밍
- 요즘은 함수형 프로그래밍이 인기~!
교착상태
- dead lock -사거리 한가운데 교통사고... 사거리 뒤에 차들 다 막혀있는 상태
기아 상태
- cpu 자원을 못 먹는 상태 – 검색해보자~
cpu가 쓰레드들에게 자원을 주는데 –
그 스케줄을 cpu스케줄러가 조정 – 고려해야 함
t1, t2중 항상 t1이 먼저 시작 안될 수도 있음
- sync 싱크로나이즈 – 동기화
- 중간에 줄 그어지는 메서드들 - Deprecated 메서드
- 버전 업그레이드되면 사라질 수도 있는 애들
review
Thread
쓰레드를 생성하는 3가지 방법!
사용하는 여러 가지 방법!
쓰레드는 한 가지 일만 하는 것인지 알게 되었고,
만드는 방법 3가지의 특징과 만드는 상황을 알 수 있었다.
오버 라이딩은 run() 메서드
실행은 start() 메서드로 하는 부분도 새로웠다.
이론적으로만 배웠던 프로세스의 상태
[ 생성 - 준비 - 실행 - 대기 ]를
sleep(), wait(), notify() 등
여러 가지 사용방법을 실습해 보면서 이해할 수 있어서 좋았다.
이제 쓰레드를 생성하고 사용하는 기초를 배웠으니
쓰레드를 활용해서 프로그래밍하는 연습을 더 하면 될 듯.
화이팅!!ㅎㅎ
'Java 기반 클라우드 융합 개발자 과정 - KH 정보교육원 > 5월' 카테고리의 다른 글
22. 05. 10 - 2차 시험, Api, 네트워크 소켓 복습 (0) | 2022.05.13 |
---|---|
22. 05. 09 - 네트워크 프로그래밍( SeverSocket, Socket ) // feat. Queue, List (0) | 2022.05.12 |
22. 05. 06 - 네트워크 프로그래밍( OSI 7Layor, Sever, Client ) (0) | 2022.05.12 |
22. 05. 03 - escape문자, printf, 고민상담, 사진2장(현재와 미래의 나) (0) | 2022.05.11 |
22. 05. 02 - 입출력(IO), 스트림(Stream), try with resource (0) | 2022.05.11 |