쓰레드 part1

Shaun·2021년 9월 11일
0

JAVA

목록 보기
18/30

쓰레드

  • 프로세스는 공장 쓰레드는 공장에서 일하는 일꾼 으로 생각하면 쉽다

  • 모든 쓰레드는 최소한 하나 이상의 쓰레드가 존재하며 개수는 제한되어 있지 않다.

  • CPU의 코어 가 한번에 단 하나의 작업만 수행할 수 있으므로 실제로 동시에 처리되는 작업의 개수는 코어의 개수와 일치한다.

  • 하나의 쓰레드를 가진 프로세스보다 두 개의 쓰레드를 가진 프로세스 가 오히려 더 낮은 성능을 보일수도 있다.

멀티쓰레드

멀티쓰레드 장점

  • CPU의 사용률을 향상
  • 자원을 보다 효율적으로 사용 가능
  • 사용자에게 대한 응답성 향상
  • 작업이 분리되어 코드 간결

멀티쓰레드 단점

  • 여러 쓰레드가 같은 프로세스 내에서 자원을 공유 하면서 작업을 하면 1.동기화2.교착상태 같은 문제를 유발 할수 있다.

교착상태: 두 쓰레드가 자원을 점유한 상태에서 서로 상대편이 점유한 자원을 사용하려고 기다리느라 진행이 멈춰 있는 상태

쓰레드의 구현과 실행

쓰레드 구현 방법

  1. Thread클래스 상속받는 방법

  2. Runnable인터페이스를 구현하는 방법

=> Runnable인터페이스는 오로지 run()만 정의되어 있는 간단한 인터페이스다.

=> Runnable 인터페이스를 구현한 경우
Runnable 인터페이스를 구현한 클래스의 인스턴를 생성한 다음 이 인스턴스를 Thread클래스의 생성자의 매개변수로 제공 해야한다.

쓰레드 메서드


  • 쓰레드 클래스를 상속 받으면 자손 클래스에서 조상 Thread클래스의 메서드를 직접 호출 할수 있다.

  • runnable 인터페이스는 Thread클래스의 static메서드인 currentThread() 를 호출하여 쓰레드에대한 참조를 얻고 해야한다.

쓰레드의 실행 -start()

  • start()가 호출 되었다고 바로 실행 되는것이 아니라 실행 대기 상태에 있다가 자신의 차례가 되면 실행된다.

  • 실행이 한번 종료된 쓰레드는 다시 실행 불가 -> 새로운 쓰레드를 생성한다음 start() 호출

Start() 와 Run()

  • Run()을 호출하는 것은 생성된 쓰레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출 하는 것이다.

  • Start()는 새로운 쓰레드가 작업을 실행하는데 필요한 호출 스택을 생성한 다음에 run()을 호출해서 생서된 호출스택에 run()이 첫 번쨰로 올라가게 한다.

  • 모든 쓰레드들은 독립적인 작업수행을 위해 자신만의 호출스택이 필요하다.

1 = main메서드에서 쓰레드의 start()를 호출한다

2 = start()는 새로운 쓰레드를 생성하고 쓰레드가 작업하는 공간, 사용될 호출스택 생성

3 = 새로 생성된 호출스택에 run()이 호출되어 쓰레드가 독립된 공간에서 작업 수행을 한다.

4 = 호출 스택이 2개이므로 스케줄러가 정한 순서에 의해서 번갈아 가면서 실행된다.

쓰레드 특징

  • 작업을 주어진 시간에 마치지 못한 쓰레드는 다시 자신의 차례가 돌아올 때까지 대기상태로 있게된다.

  • 작업을 마친 쓰레드 즉 run()의 수행이 종료된 쓰레드는 호출 스택이 모두 비워지며 이 호출스택은 사라진다.

  • main 메서드가 수행을 마치면 프로그램이 종료 되었으나, 다른 쓰레드가 아직 작업을 마치지 않은 상태이면 프로그램은 종료되지 않는다.

실행 중인 사용자 쓰레드가 하나도 없을 떄 프로그램은 종료된다.

ex 1

  • 호출스택의 첫 번쨰 메서드가 main메서드가 아니라 run 메서드인 것을 확인하자.

  • 한 쓰레드의 예외가 발생해서 종료되어도 다른 쓰레드의 실행에는 영향을 주지 않는다. (독립적이다)

  • main 쓰레드는 이미 종료

ex 2

  • start()가 없으므로 쓰레드가 새로 생성되지 않았다 (=호출 스택 새로 생성 x)

  • 쓰레드가 생성된게 아니라 그냥 run()메서드만 호출 된것일뿐이다( 위의 예제와 차이점을 유의하자)

싱글쓰레드 VS 멀티쓰레드

  • 일하는 일꾼(쓰레드) 가많으면 작업이 더빨리 끝날줄 알았지만 작업전환 이란것 떄문에 시간이 더걸린다.

  • 프로세스 또는 쓰레드 간의 작업 전환을 '컨텍스트 스위칭' 이라한다.

  • 그래서 간단한 작업은 오히려 싱글 쓰레드가 더빠르다.

  • 한 쓰레드가 화면에 출력하고 있는동안 다른 쓰레드는 출력이 끝나기를 기다려야 하기 떄문에 시간이 더 걸린다

  • 싱글 코어 인경우 두 작업이 절대 겹치지 않지만 멀티 코어에 멀티 쓰레드인 경우에는 겹치는 부분이 발생한다. 그래서 화면(CONSOLE)라는 자원을 놓고 두 쓰레드가 경쟁하는 것이다.

-> 위의 결과는 실행할때마다 다른 결과를 얻는데 그 이유는 예제프로그램이 os의 프로세스 스케줄러의 영향을 받기 떄문

하!지!만!

  • 두 쓰레드가 서로 다른 자원을 사용하는 작업에서는 멀티 쓰레드가 더 효율적이다.

  • 우리가 평소에 컴퓨터를 사용할떄 카톡을 키고 음악을 키고 작업을 하는 상상을 해보자. 싱글 쓰레드 였으면 노래 듣는동안 다른 작업은 아무것도 할수 없다.

하나의 자원(싱글win) vs 다른자원 (멀티쓰레드 win)

쓰레드의 우선순위

  • 쓰레드가 수행하는 작업의 중요도에 따라 쓰레드의 우선순위를 서로 다르게 지정하여 특정 쓰레드가 더 많은 작업 시간을 갖도록 할수 있다.

  • 쓰레드가 가질수 있는 우선순위의 범위는 1 부터 10 이며 숫자가 높을수록 우선순위가 높다.

  • 우선순위는 쓰레드를 생성한 쓰레드로부터 상속 받는다.

  • main 메서드를 수행하는쓰레드는 우선순위가 5이다.

  • t1, t2 모두 main 메서드에서 생성하였기 떄문에 우선순위 5이다. t2는 setPriority(7)을 통해 우선순위를 7로 변경했다. 그다음 start()를 호출했다.

  • 이 처럼 쓰레드를 실행하기 전에만 우선순위를 변경 할수 있다.

  • 하지만 멀티코어에서는 쓰레드의 우선순위에 따른 차이가 전혀 없다... -> 우선순위에 차등을 두어 쓰레드를 실행시키는 것은 별 효과 없다.

=> 멀티 코어라 해도 os마다 다른 방식으로 스케쥴링 하기 떄문에 os마다 다른 결과가 나온다.

profile
호주쉐프에서 개발자까지..

0개의 댓글