Java/Java

Java 12. 쓰레드 ( Thread )

shin96bc 2022. 3. 11. 11:08

(1) 정의
     1) process 를 구성하는 '제어의 흐름'

 

(2) process 와 Thread
     1) Process: 프로그램 '실행단위' 이다.
     2) Thread: Process를 구성하는 '작업단위' 이다.

 

(3) 장점
     1) 하나의 Process로 여러개의 일을 동시에 수행한다.
     2) '경량프로세스'라고 불리우기도 할 정도로 가볍다.
     3) 가벼운 이유는 공통 Resource를 공유하기 때문이다.

 

(4) 비유: '피고용인'(Emploee)

 

(5) 생성 
     1) java.lang.Thread 를 상속( extends ) 받는다. ( 클래스 )
     2) java.lang.Runnable 을 구현( implements ) 한다. ( 인터페이스 )

 

(6) 시작
     1) class Gth1 extends Thread {}

        Thread th = new Gth1();

        th.start();

 

     2) class Gth2 implements Runnable {}

        Runnable r = new Gth2();
        Thread th2 = new Thread(r);
        th2.start();

 

    3) class Gth3 implements Runnable {}
        Thread th3 = new Thread(this);
        th3.start();

 

(7) LifeCycle
     1) 5가지 상태
     2) 각 상태는 '메소드'나 '스케쥴러'나 '시간'이나 '상황'에 의해 이동한다.
     3) 한번 돌아가시면 살아나지 못한다.

 

(8) Priority
     1) Ready상태의 쓰레드중에서 우선적으로 CPU를 점유할 수 있는 쓰레드를 판별하기 위한 LEVEL 값이다.

     2) 범위
          1~10

     3) Thread.MAX_PRIORITY  //10
        Thread.MIN_PRIORITY  // 1
        Thread.NORM_PRIORITY  // 5

     4) 부여/조회
        th.setPriority(int new Priority);
        th.getPriority()

     5) 우선순위를 높이면 스케쥴러에 의해 뽑힐 확률이 높아진다.

 

(9) 동기화
     1) 무결성이 깨지는 '극단적인 예'

          <1> 하나의 메소드를 두개의 쓰레드가 동시에 접근하는경우 무결성이 깨진다.
               ex) class Ith1 extends Thread {
                         public void run(){
                              I.m();
                         }
                    }
                    class Ith2 extends Thread {
                         public void run(){
                              I.m();
                         }
                    }

                    class I {
                         static int i;
                         I(){
                              Thread th1 = new Ith1();
                              Thread th2 = new Ith2();
                              th1.start();
                              th2.start();

                              try{
                                   th1.join();
                                   th2.join();
                              }catch(InterruptedException ie){}
                         }
                          synchronized static void m(){
                               for(int j=0; j<1000000; j++){
                                    i++;
                               }
                          }

               1> 결과값으로 2000000 이 나와야 정상인데, 무결성이 깨지기 때문에 다른 값이 나온다.   

               2> 값을 증가시키고 그 값을 i 에 저장하는 단계에 다른 쓰레드가 접근하면 다시 i 값을 읽기 때문에

                    다시 i값이 0 이 되어버린다. 그래서 저장하는 단계에서 i 값이 0 이 저장되게 되서 무결성이 깨진다.    


          <2> CPU 연산 단계 #                  Ith1     Ith2  
               1> 현재 i값을 읽는 단계         i==0    i==0
               2> 값을 증가시키는 단계        i==0    i==0
               3> 증가된 값을 i에 저장 단계   i==1    i==1

      3) 비유: 화장실의 문고리

      4) 설명: 하나 이상의 쓰레드가 어떤 연산 or 로직에 동시에 접근했을 때,
                그 연산에 대해 값의 무결성을 보장하기 위해서 수행영역에 대한 lock을 걸어주는 것이다.

      5) 방법
           <1> synchronized void m(){
                       동기화가 필요한 로직;
                  } 

           <2> void m(){
                       일반로직;
                       synchronized(this){
                            동기화가 필요한 로직;
                       }
                  }

'Java > Java' 카테고리의 다른 글

Java 14. IO( Input Output )  (0) 2022.03.11
Java 13. 람다식  (0) 2022.03.11
Java 11. 어노테이션 ( Annotation )  (0) 2022.03.11
Java 10. 내부클래스 ( Inner Class )  (0) 2022.03.10
Java 09. this 와 super  (0) 2022.03.10