자바 스 레 드 상태 및 전환,스 레 드 를 닫 는 정확 한 자세 공유

머리말
스 레 드 를 말 하기 전에 프로 세 스 의 정 의 를 토론 할 필요 가 있 습 니 다.프로 세 스 는 프로그램 이 데이터 집합 에서 실행 되 는 과정 으로 시스템 이 자원 배분 과 배 치 를 하 는 독립 된 단위 입 니 다.프로 세 스 실 체 는 프로그램 세그먼트,데이터 세그먼트 PCB(프로 세 스 제어 블록)로 구성 되 어 있 습 니 다.스 레 드 는 또 뭐야?스 레 드 는 경량급 프로 세 스 로 볼 수 있 습 니 다.스 레 드 는 프로 세 스 의 실행 단위 이 고 프로 세 스 스케줄 의 기본 단위 입 니 다.
본 고 는 자바 스 레 드 상태 및 전환,스 레 드 닫 기 에 관 한 내용 을 상세 하 게 소개 할 것 입 니 다.다음은 더 이상 말 하지 않 겠 습 니 다.상세 한 소 개 를 살 펴 보 겠 습 니 다.
1.스 레 드 상태 및 전환
자바 의 스 레 드 는 여섯 가지 상태 가 있 습 니 다.스 레 드 안의 매 거 진 클래스 를 사용 하여 이 루어 집 니 다.다음 과 같이 저 는 모든 상태 에 대해 어느 정도 설명 을 했 습 니 다.

public enum State {
  /**           (    start  )*/
  NEW,

  /**
   * JVM               ,            JVM   ,
   *     ,          JVM           。
   */
  RUNNABLE,

  /**
   *                   ,
   *       ,         ,       
   *       ,    RUNNABLE  
   */
  BLOCKED,

  /**
   *    Object.wait、Thread.join  LockSupport  park     ,       ,
   *              ,       。
   *        :Object.notify(      )、Object.notifyAll(      ),
   *           RUNNABLE  
   */
  WAITING,

  /**
   *  WAITING  ,                   ,
   *   :Object.wait(10)、Thread.sleep(10)、Thread.join(10)、LockSupport.parkNanos(10)、LockSupport.parkUntil(10)    
   *         :
   *  1、    。
   *  2、       notify  notifyAll
   *         RUNNABLE  
   */
  TIMED_WAITING,

  /**      (         )*/
  TERMINATED;
 }
NEW 와 TERMINATED 를 제외 하고 다른 상 태 는 서로 전환 할 수 있 으 며 그 전환 과정 은 다음 그림 과 같다.

여기 서 특히 RUNNABLE 상 태 를 말씀 드 리 겠 습 니 다.이 상태 에서 스 레 드 가 반드시 프로그램 을 실행 하 는 것 은 아 닙 니 다.JVM 에 의 해 배 치 된 스 레 드 만 실행 되 는 시간 영 화 를 얻 을 수 있 고 이 상태의 스 레 드 만 시간 영 화 를 얻 을 수 있 습 니 다.다시 말 하면 JVM 에 의 해 배 치 된 스 레 드 는 RUNNABLE 상태 스 레 드 에 만 속 하 는 권리 입 니 다.이해 하기 편리 하도록 RUNABLE 을 Runnable 과 Running 두 가지 상태 로 나 눌 수 있 습 니 다.(물론 다른 것 으로 바 꿀 수도 있 습 니 다.여 기 는 제 가 잘 이해 할 수 있 을 뿐 입 니 다)그러면 위의 스 레 드 전환 도 는 아래 와 같이 바 뀌 었 습 니 다.(의 스 레 드 상태 도 참조)

스 레 드 상태 전환 의 예 는 아래 코드 를 통 해 깊이 이해 할 수 있 습 니 다.

public class Test {
 public static void main(String[] args) {
  Test test = new Test();
  // 1.NEW  
  Thread thread = new Thread(() -> {
   // 3.  test      ,         ,    BLOCKED      ,       RUNNABLE 
   synchronized (test) {
    try {
     // 4.  TIMED_WAITING  ,100ms     RUNNABLE        
     Thread.sleep(100);
     // 5.         ,  WAITING   
     test.wait();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   // 6.  run()           ,  TERMINATED 
  });
  // 2.  start()  ,    RUNNABLE  
  thread.start();
 }
}

 :             
2.스 레 드 를 정확하게 끝 냅 니 다.
위의 예 에서 우 리 는 스 레 드 의 run 방법 이 정상적으로 실 행 된 후에 스 레 드 가 정상적으로 사망 하여 TERMINATED 상태 에 들 어 가 는 것 을 보 았 습 니 다.만약 에 우리 가 중간 에 스 레 드 를 멈 추 는 수요 가 있다 면 우 리 는 어떻게 스 레 드 를 정확하게 끝내 야 합 니까?
interrupt()방법 을 사용 합 니 다.스 레 드 내부 에서 현재 스 레 드 가 끊 긴 상태 에 있 는 지 여 부 를 표시 하 는 변 수 를 정 의 했 습 니 다.interrupt()방법 을 사용 하면 이 상 태 를 true 로 바 꿉 니 다.우 리 는 이 방법 으로 이상 처 리 를 하 는 방식 으로 스 레 드 를 끝 냈 다.

  public static void main(String[] args) {
  Thread thread = new Thread(() -> {
   try {
    Thread.sleep(1);
   } catch (InterruptedException e) {
    e.printStackTrace();
    //    return    ,      
    return;
   }
   System.err.println("thread interrupt test...");
  });
  thread.start();
  thread.interrupt();
  System.out.println("main thread end...");
 }

//    :           

여기 서 스 레 드 의 끊 어 진 표지 변수(그 다음 에 interrupt 으로 말 함)에 대해 설명 할 것 은 특정한 상황 에서 그 상태 가 초기 화 된다 는 것 이다.
1.스 레 드 내부 가 catch 에 이상 이 생기 면 interrupt 의 상 태 는 false 로 초기 화 됩 니 다.
2.스 레 드 가 Thread.interrupted()방법 을 호출 하면 interrupt 의 상 태 는 false 로 초기 화 됩 니 다.스 레 드 가 중단 되 었 는 지 판단 하려 면 대상 방법 인 isInterrupted()를 사용 할 수 있 습 니 다.이 방법 은 리 셋 되 지 않 습 니 다.
그래서 아까 코드 에 return 을 추가 하여 스 레 드 를 끝내 야 합 니 다.그렇지 않 으 면 스 레 드 는 계속 아래로 실 행 됩 니 다.다음 그림 과 같 습 니 다.

isInterrupted()를 사용 하여 구현:

public static void main(String[] args) throws InterruptedException {
 Thread thread = new Thread(() -> {
  while (!Thread.currentThread().isInterrupted()) {
   int k = 0;
   while (k++ < 10) {
    System.out.println("do something..." + k);
   }
  }
 System.err.println("thread end...");
 });
 thread.start();
 Thread.sleep(1);
 //          ,      
 thread.interrupt();
}
표지 위 치 를 사용 하여 실현 합 니 다.변수 표지 스 레 드 가 종료 되 는 지 여 부 를 정의 하고 종료 되면 run 방법 을 종료 합 니 다.위의 isInterrupted()의 실현 과 마찬가지 로 volatile 변수 로 바 뀌 었 을 뿐이다.

public class Test {

 public static volatile boolean interrupted = false;

 public static void main(String[] args) throws InterruptedException {
  Thread thread = new Thread(() -> {
   while (!interrupted) {
    int k = 0;
    while (k++ < 10) {
     if (interrupted) {
      System.err.println("thread invoke end....");
      return;
     }
     System.out.println("do something..." + k);
    }
   }
  System.err.println("thread end...");
  });
  thread.start();
  Thread.sleep(1);
  //          ,      
  interrupted = true;
 }
}
//    

stop()방법-부정 확 한 스 레 드 중단 방법
스 레 드 가 제공 하 는 방법 중 하 나 는 스 레 드 인 stop()을 강제로 닫 을 수 있 는 방법 도 있다.이 방법 은 상당히 포악 하 다 고 할 수 있 습 니 다.사람들 에 게'나 는 상관 하지 않 습 니 다.나 는 당신 이 지금 당장 죽 기 를 원 합 니 다(스 레 드 를 가리 키 는 말)'라 는 느낌 을 주 고 스 레 드 의 모든 잠 금 자원 을 방출 합 니 다.그러면 데이터 가 일치 하지 않 아 스 레 드 가 안전 하지 않 은 상황 이 발생 할 수 있 습 니 다.예 를 들 어 다음 과 같 습 니 다.

public class Test {

  public static volatile boolean flag = false;
  public int state = 0;

  public static void main(String[] args) throws InterruptedException {
   Test test = new Test();
   Thread thread = new Thread(() -> {
    synchronized (test) {
     try {
      test.state = 1;
      Thread.sleep(100);
      if (flag) {
       test.state = 2;
      }
      System.err.println("thread execute finished...");
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   });
   thread.start();
   Thread.sleep(1);
   thread.stop();
   flag = true;
   System.out.println("state  :" + test.state);
  }
}
//       ,        state  1,                   state  2,           ,        ,                 ,          。
//    

그래서 우 리 는 스 톱()이 아 닌 위의 두 가지 정확 한 방식 으로 스 레 드 를 중지 해 야 한다.또한 stop()방법 은 스 레 드 start()전에 실행 되면 스 레 드 가 시 작 될 때 바로 사망 합 니 다.
잘못된 점 이 있 으 면 아 낌 없 는 가르침 을 바 랍 니 다.
총결산
이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기