JAVA 스 레 드 를 자세히 알 아 보 세 요.-스 레 드 상 태 는 어떤 게 있 나 요?그것 은 어떻게 일 합 니까?

10921 단어 JAVA스 레 드상태.
스 레 드(Thread)는 병행 프로 그래 밍 의 기초 이자 프로그램 이 실행 하 는 최소 단위 로 프로 세 스 에 의존 하여 존재 합 니 다.
하나의 프로 세 스 에는 여러 개의 스 레 드 가 포함 되 어 있 습 니 다.다 중 스 레 드 는 메모리 공간 과 시스템 자원 을 공유 할 수 있 기 때문에 스 레 드 간 의 전환 은 자원 을 더욱 절약 하고 경 량 화 되 기 때문에 경량급 프로 세 스 라 고 불 립 니 다.
스 레 드 의 상 태 는 JDK 1.5 이후 Thread 의 소스 코드 에 매 거 진 방식 으로 정의 되 었 습 니 다.총 6 개의 상 태 를 포함 합 니 다.
  • NEW,새 상태,스 레 드 가 생 성 되 었 으 나 시작 되 지 않 았 을 때의 스 레 드 상태;
  • RUNNABLE,준비 상태,실행 가능 한 스 레 드 상 태 를 표시 합 니 다.실행 중이 거나 운영 체제 가 CPU 자원 을 할당 하 기 를 기다 리 고 있 을 수도 있 습 니 다.
  • BLOCKED 는 잠 금 을 기다 리 는 스 레 드 상 태 를 차단 하고 차단 상태 에 있 는 스 레 드 가 모니터 잠 금 을 기다 리 고 있 음 을 나타 낸다.예 를 들 어 synchronized 코드 블록 을 실행 하거나 synchronized 표 시 를 사용 하 는 방법 등 이다.
  • WAITING,대기 상태,대기 상태 에 있 는 스 레 드 는 다른 스 레 드 가 특정한 동작 을 수행 하 기 를 기다 리 고 있 습 니 다.예 를 들 어 하나의 스 레 드 가 Object.wait()방법 을 호출 하면 다른 스 레 드 가 Object.notify()또는 Object.notify All()방법 을 호출 하 기 를 기다 리 고 있 습 니 다.
  • TIMED_WAITING,타이머 대기 상태,대기 상태(WAITING)와 유사 합 니 다.시간 초과 설정 방법 이 있 는 Object.wait(long timeout)와 Thread.join(long timeout)등 을 호출 했 을 때 만 이 상태 에 들 어 갈 수 있 습 니 다.
  • TERMINATED,종료 상 태 는 스 레 드 가 완료 되 었 음 을 나타 낸다.
  • 스 레 드 상태의 소스 코드 는 다음 과 같 습 니 다.
    
    public enum State {
     /**
      *     ,       ,           
      */
     NEW,
     /**
      *     ,           ,               CPU   
      */
     RUNNABLE,
     /**
      *           ,             
      *         ,       synchronized      
      *    synchronized      
      */
     BLOCKED,
     /**
      *     ,                             。
      *   ,        Object.wait()            
      * Object.notify()   Object.notifyAll()
      */
     WAITING,
     /**
      *       ,      (WAITING)   ,        ,  
      *               Object.wait(long timeout)   
      * Thread.join(long timeout)        
      */
     TIMED_WAITING,
     /**
      *     ,          
      */
    
    }
    스 레 드 의 작업 모드 는 먼저 스 레 드 를 만 들 고 스 레 드 가 실행 해 야 할 업무 방법 을 지정 한 다음 에 스 레 드 의 start()방법 을 호출 하 는 것 입 니 다.이때 스 레 드 는 NEW(새로 만 들 기)상태 에서 RUNNABLE(준비)상태 로 바 뀌 었 습 니 다.
    그 다음 에 스 레 드 는 실행 할 방법 중 synchronized 동기 코드 블록 이 있 는 지 판단 합 니 다.다른 스 레 드 도 이 자 물 쇠 를 사용 하면 스 레 드 는 BLOCKED(대기 차단)상태 로 변 합 니 다.다른 스 레 드 가 이 자 물 쇠 를 사용 한 후에 스 레 드 는 남 은 방법 을 계속 실행 합 니 다.
    Object.wait()또는 Thread.join()방법 을 만 났 을 때 스 레 드 는 WAITING(대기 상태)상태 로 변 합 니 다.
    시간 초과 대기 방법 이 있 으 면 스 레 드 는 TIMED 에 들 어 갑 니 다.WAITING(타이머 대기)상태;
    다른 스 레 드 가 notify()또는 notify All()방법 을 실행 한 후에 스 레 드 는 나머지 업무 방법 을 계속 실행 하 는 것 을 깨 워 서 방법 이 실 행 될 때 까지 전체 스 레 드 의 절 차 는 실 행 됩 니 다.실행 절 차 는 다음 그림 과 같 습 니 다.

    [BLOCKED 와 WAITING 의 차이 점]
    BLOCKED 와 WAITING 은 기다 린 다 는 의미 가 있 지만 본질 적 인 차이 가 있다.
    우선 이들 상태 에서 형 성 된 호출 방법 은 다르다.
    그 다음 에 BLOCKED 는 현재 스 레 드 가 활성 상태 에 있 고 다른 스 레 드 가 특정한 잠 금 자원 을 사용 하 기 를 기다 리 는 것 을 막 는 것 으로 이해 할 수 있 습 니 다.
    한편,WAITING 은 Object.wait()또는 Thread.join()또는 LockSupport.park()를 자체 호출 하여 대기 상태 에 들 어 갔 기 때문에 다른 스 레 드 가 특정한 동작 을 수행 할 때 까지 기 다 려 야 계속 깨 어 날 수 있 습 니 다.
    예 를 들 어 스 레 드 가 Object.wait()를 호출 하여 WAITING 상태 에 들 어간 후에 다른 스 레 드 가 Object.notify()나 Object.notify All()을 실행 할 때 까지 기 다 려 야 깨 어 날 수 있 습 니 다.
    [start()와 run()의 차이 점]
    먼저 Thread 소스 코드 를 보면 start()방법 은 Thread 자체 의 방법 에 속 하고 synchronized 를 사용 하여 스 레 드 안전 을 확보 합 니 다.소스 코드 는 다음 과 같 습 니 다.
    
    public synchronized void start() {
    
     //     ,    NEW         
    
     if (threadStatus != 0)
    
      throw new IllegalThreadStateException();
    
     //      ,       
    
     group.add(this);
    
     boolean started = false;
    
     try {
    
      start0();
    
      started = true;
    
     } finally {
    
      try {
    
       if (!started) {
    
        group.threadStartFailed(this);
    
       }
    
      } catch (Throwable ignore) {
    
       //        ,   start0     ,            
    
      }
    
     }
    
    }
    run()방법 은 Runnable 의 추상 적 인 방법 입 니 다.호출 클래스 에서 이 방법 을 다시 써 야 합 니 다.다시 쓰 는 run()방법 은 바로 이 스 레 드 가 실행 할 업무 방법 입 니 다.소스 코드 는 다음 과 같 습 니 다.
    
    public class Thread implements Runnable {
    
     //       ......
    
     private Runnable target;
    
     @Override
    
     public void run() {
    
      if (target != null) {
    
       target.run();
    
      }
    
     }
    
    }
    
    @FunctionalInterface
    
    public interface Runnable {
    
     public abstract void run();
    
    }
    실행 효과 에 있어 start()방법 은 다 중 스 레 드 를 열 어 NEW 상태 에서 RUNABLE 상태 로 전환 시 킬 수 있 으 며,run()방법 은 일반적인 방법 일 뿐이다.
    그 다음으로 호출 가능 한 횟수 가 다 르 기 때문에 start()방법 은 여러 번 호출 될 수 없습니다.그렇지 않 으 면 자바.lang.IllegalState Exception 을 던 집 니 다.run()방법 은 일반적인 방법 일 뿐 이기 때문에 여러 번 호출 할 수 있다.
    [스 레 드 우선 순위]
    Thread 소스 코드 에서 스 레 드 우선 순위 와 관련 된 속성 은 3 개 입 니 다:
    
    //             
    
    public final static int MIN_PRIORITY = 1;
    
    //        
    
    public final static int NORM_PRIORITY = 5;
    
    //             
    
    public final static int MAX_PRIORITY = 10
    스 레 드 의 우선 순 위 는 스 레 드 가 CPU 시간 편 을 선점 할 확률 로 이해 할 수 있 습 니 다.우선 순위 가 높 을 수록 스 레 드 가 우선 실 행 될 확률 이 높 지만 우선 순위 가 높 은 스 레 드 가 반드시 먼저 실 행 될 것 이 라 고 보장 할 수 없습니다.
    프로그램 에서 우 리 는 Thread.setPriority()를 통 해 우선 순 위 를 설정 할 수 있 습 니 다.setPriority()소스 코드 는 다음 과 같 습 니 다.
    
    public final void setPriority(int newPriority) {
    
     ThreadGroup g;
    
     checkAccess();
    
     //           
    
     if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
    
      throw new IllegalArgumentException();
    
     }
    
     if((g = getThreadGroup()) != null) {
    
      //                 ,                 
    
      if (newPriority > g.getMaxPriority()) {
    
       newPriority = g.getMaxPriority();
    
      }
    
      setPriority0(priority = newPriority);
    
     }
    
    }
    [라인 의 상용 방법]
    스 레 드 의 상용 방법 은 다음 과 같은 몇 가지 가 있다.
    join()
    한 스 레 드 에서 other.join()을 호출 합 니 다.이 때 현재 스 레 드 는 other 스 레 드 가 실행 되 거나 시간 이 지나 면 현재 스 레 드 를 계속 실행 합 니 다.join()소스 코드 는 다음 과 같 습 니 다.
    
    public final synchronized void join(long millis)
    
    throws InterruptedException {
    
     long base = System.currentTimeMillis();
    
     long now = 0;
    
     //          0
    
     if (millis < 0) {
    
      throw new IllegalArgumentException("timeout value is negative");
    
     }
    
     //    0       ,         
    
     if (millis == 0) {
    
      //       (    )      ,     
    
      while (isAlive()) {
    
       wait(0);
    
      }
    
     } else {
    
      //     
    
      while (isAlive()) {
    
       long delay = millis - now;
    
       if (delay <= 0) {
    
        break;
    
       }
    
       wait(delay);
    
       now = System.currentTimeMillis() - base;
    
      }
    
     }
    
    }
    원본 코드 에서 알 수 있 듯 이 join()방법의 밑바닥 은 wait()방법 을 통 해 이 루어 진다.
    예 를 들 어 join()을 사용 하지 않 았 을 때 코드 는 다음 과 같 습 니 다.
    
    public class ThreadExample {
    
     public static void main(String[] args) throws InterruptedException {
    
      Thread thread = new Thread(() -> {
    
       for (int i = 1; i < 6; i++) {
    
        try {
    
         Thread.sleep(1000);
    
        } catch (InterruptedException e) {
    
         e.printStackTrace();
    
        }
    
        System.out.println("     :" + i + " 。");
    
       }
    
      });
    
      thread.start(); //     
    
      //      
    
      for (int i = 1; i < 4; i++) {
    
       try {
    
        Thread.sleep(1000);
    
       } catch (InterruptedException e) {
    
        e.printStackTrace();
    
       }
    
       System.out.println("     :" + i + " 。");
    
      }
    
     }
    
    }
    프로그램 실행 결 과 는:
    주 스 레 드 수면 복사:1 초.
    서브 스 레 드 수면:1 초.
    주 스 레 드 수면:2 초.
    서브 스 레 드 수면:2 초.
    주 스 레 드 수면:3 초.
    서브 스 레 드 수면:3 초.
    서브 스 레 드 수면:4 초.
    서브 스 레 드 수면:5 초.
    결 과 를 보면 join()을 사용 하지 않 을 때 메 인 스 레 드 가 교체 되 어 실 행 됩 니 다.
    그리고 우 리 는 join()방법 을 코드 에 넣 었 습 니 다.코드 는 다음 과 같 습 니 다.
    
    public class ThreadExample {
    
     public static void main(String[] args) throws InterruptedException {
    
      Thread thread = new Thread(() -> {
    
       for (int i = 1; i < 6; i++) {
    
        try {
    
         Thread.sleep(1000);
    
        } catch (InterruptedException e) {
    
         e.printStackTrace();
    
        }
    
        System.out.println("     :" + i + " 。");
    
       }
    
      });
    
      thread.start(); //     
    
      thread.join(2000); //          2   
    
      //      
    
      for (int i = 1; i < 4; i++) {
    
       try {
    
        Thread.sleep(1000);
    
       } catch (InterruptedException e) {
    
        e.printStackTrace();
    
       }
    
       System.out.println("     :" + i + " 。");
    
      }
    
     }
    
    }
    프로그램 실행 결 과 는:
    하위 스 레 드 수면 복사:1 초.
    서브 스 레 드 수면:2 초.
    주 스 레 드 수면:1 초.
    // thread.join(2000); 2 초 를 기다 린 후 메 인 스 레 드 와 하위 스 레 드 를 교체 하여 실행 합 니 다.
    서브 스 레 드 수면:3 초.
    주 스 레 드 수면:2 초.
    서브 스 레 드 수면:4 초.
    서브 스 레 드 수면:5 초.
    주 스 레 드 수면:3 초.
    실행 결 과 를 통 해 알 수 있 듯 이 join()방법 을 추가 한 후에 메 인 스 레 드 는 2 초 후에 야 계속 실 행 됩 니 다.
    yield()
    Thread 의 소스 코드 를 보면 yield()를 로 컬 방법 으로 알 수 있 습 니 다.즉,yield()는 C 또는 C++로 이 루어 진 것 입 니 다.소스 코드 는 다음 과 같 습 니 다.
    
    public static native void yield();
    yield()방법 은 현재 스 레 드 스케줄 러 에 CPU 사용권 을 양도 하 겠 다 는 암 시 를 표시 하지만 스 레 드 스케줄 러 는 이 암 시 를 무시 할 수 있 습 니 다.
    예 를 들 어 우 리 는 이 단락 에 yield()방법 을 포함 하 는 코드 를 실행 합 니 다.다음 과 같 습 니 다.
    
    public static void main(String[] args) throws InterruptedException {
    
     Runnable runnable = new Runnable() {
    
      @Override
    
      public void run() {
    
       for (int i = 0; i < 10; i++) {
    
        System.out.println("  :" +
    
          Thread.currentThread().getName() + " I:" + i);
    
        if (i == 5) {
    
         Thread.yield();
    
        }
    
       }
    
      }
    
     };
    
     Thread t1 = new Thread(runnable, "T1");
    
     Thread t2 = new Thread(runnable, "T2");
    
     t1.start();
    
     t2.start();
    
    }
    이 코드 를 여러 번 실행 한 후에 매번 실 행 된 결과 가 다르다 는 것 을 알 게 될 것 입 니 다.이것 은 yield()의 실행 이 매우 불안정 하기 때 문 입 니 다.스 레 드 스케줄 러 가 반드시 yield()가 CPU 사용권 을 양도 하 는 건 의 를 받 아들 이지 않 아서 이런 결 과 를 초래 했 습 니 다.
    지금까지 JAVA 스 레 드 를 자세히 알 아 봤 습 니 다.-스 레 드 상 태 는 어떤 게 있 나 요?그것 은 어떻게 일 합 니까?자바 스 레 드 에 관 한 더 많은 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기