스 레 드 인 터 럽 트
                                            
 6997 단어  자바
                    
stop(), suspend() 등 스 레 드 를 끊 는 방법 을 제공 하 였 으 나, 안전 문제 로 인해 현재 모두 폐기 되 었 다.자바 는 스 레 드 를 중단 하 는 안전 한     방법 을 제공 하지 않 았 으 나 중단 (Interruption) 을 제공 합 니 다. 이것 은      방식 으로 다른 스 레 드 의 현재 작업 을 중단 시 킵 니 다.이러한 협력 식 방법 은 필요 하 다. 우 리 는 특정한 임무, 스 레 드 또는 서비스 가 즉시 중단 되 기 를 원 하지 않 는 다. 왜냐하면 이러한 즉시 중단 은 공 유 된 데이터 구 조 를 일치 하지 않 는 상태 에 처 하 게 할 수 있 기 때문이다.반면 작업 과 서 비 스 를 작성 할 때 협업 방식 을 사용 할 수 있 습 니 다. 멈 춰 야 할 때 현재 실행 중인 작업 을 먼저 지우 고 끝 냅 니 다.이것 은 요청 을 취소 하 는 코드 를 보 내 는 것 보다 작업 자체 의 코드 가 제거 작업 을 어떻게 수행 하 는 지 더 잘 알 기 때문에 더욱 유연성 을 제공 합 니 다.라 이 프 사이클 종료 (End - of - Lifecycle) 의 문 제 는 임무, 서비스, 프로그램의 설계 와 실현 등 과정 을 복잡 하 게 만 들 지만 프로그램 설계 에서 매우 중요 한 요 소 는 무시 되 는 경우 가 많다.행위 가 좋 은 소프트웨어 와 억지로 실행 되 는 소프트웨어 사이 의 가장 큰 차이 점 은 행위 가 좋 은 소프트웨어 가 실패, 폐쇄, 취소 등 과정 을 완벽 하 게 처리 할 수 있다 는 것 이다.어떻게 협력 체 제 를 설계 하여 스 레 드 를 안전하게 중단 시 킬 수 있 습 니까?우 리 는 취소 표 지 를 설정 할 수 있 습 니 다. 작업 스 레 드 가 중단 되 는 곳 에서 이 표 지 를 검사 할 수 있 습 니 다. 이 중단 표지 가 취소 되 었 음 을 확인 하면 작업 스 레 드 는 취소 작업 을 시작 합 니 다.public class CancelableThread implements Runnable {
    
    //       ,volatile  ,       
    private volatile boolean isCanceled = false;
    
    @Override
    public void run() {
        while (!isCanceled) {//                
            System.out.println("The current thread is doing something...");
            System.out.println(Thread.currentThread().getName() + " cancel flag is " + isCanceled);
        }
        //          true,      ,         
        System.out.println(Thread.currentThread().getName() + "The current thread Has been cancelled");
    }
    private void cancel() {
        isCanceled = true;
    }
}public class MainTest {
    public static void main(String[] args) throws Exception {
        CancelableThread cancelableThread = new CancelableThread();
        new Thread(cancelableThread).start();
        try {
            Thread.sleep(100);
        } finally {
            //       true,       
      cancelableThread.cancel();
        }
    }
}Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is false
The current thread is doing something...
Thread-0 cancel flag is true
Thread-0The current thread Has been cancelled 위의 예 를 정리 하면 이 예 는 결함 이 있 습 니 다. run 방법 은 이렇게 쓰 면:
@Override
public void run() {
    while(!isCanceled){
        try {
            //            
            Thread.sleep(10000);
        }catch (InterruptedException e){
            //      isInterrupted  ,       
        }
    }
    //        ,    
}만약 에 현재 스 레 드 가
    방법 을 실 행 했 을 때 스 레 드 가 걸 렸 습 니 다. 표지 위치 sleep 가 어떻게 변 하 든 순환 을 벗 어 나 지 못 합 니 다. 그러면 우리 가 예상 한 결과 와 일치 하지 않 을 수 있 습 니 다. 따라서 사용자 정의 표지 위 치 를 사용 하여 스 레 드 의 중단 을 제어 하 는 것 을 권장 하지 않 습 니 다. 아래 의 방법 을 사용 해 야 합 니 다.Thread 클래스 는 상기 메커니즘 을 실현 하기 위해 세 가지 라인 중단 과 관련 된 방법 을 제공 합 니 다.이 세 가지 방법 은 다음 과 같다.
public void interrupt() {
  //...        
  interrupt0();           // Just to set the interrupt flag       
  //...        
}public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}public boolean isInterrupted() {
    return isInterrupted(false);
}isCanceled 방법 은 주로 중단 표지 위 치 를 설정 하 는 데 사용 된다.이 스 레 드 가 호출 interrupt() 방법 이나 wait, join 방법 으로 막 히 면 중단 상태 가 삭 제 됩 니 다 (즉, 스 레 드 가 중단 표지 위 치 를 무시 하지 않 습 니 다). 그리고 sleep 이상 을 받 을 수 있 습 니 다.InterruptedException 방법 은 현재 스 레 드 가 중단 되 었 는 지 테스트 하 는 데 사 용 됩 니 다. 이 방법 을 사용 하면 스 레 드 의 중단 상 태 를 제거 합 니 다.스 레 드 가 중단 되면 이 방법 을 사용 하여 false 로 되 돌려 줍 니 다.interrupted() 방법 은 현재 스 레 드 가 중단 되 었 는 지 테스트 하지만 스 레 드 의 중단 상 태 를 제거 하지 않 습 니 다.public class InterruptTest {
    static class InnerThread extends Thread{
        @Override
        public void run() {
            while(!isInterrupted()){
                System.out.println(Thread.currentThread().getName()+" cancle flag is "+isInterrupted());
                try {
                    Thread.sleep(100);
                }catch (InterruptedException e){
                    e.printStackTrace();
                    //   InterruptedException,        ,     interrupt();
                    interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName()+" cancle flag is "+isInterrupted());
        }
    }
    public static void main(String[] args) {
        InnerThread innerThread = new InnerThread();
        innerThread.start();
        try {
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        innerThread.interrupt();
//        InnerThread innerThread2 = new InnerThread();
//        innerThread2.start();
//        innerThread2.interrupt();
    }
}Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
Thread-0 cancle flag is false
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at InterruptTest$InnerThread.run(InterruptTest.java:13)
Thread-0 cancle flag is true글 의 출처 (내용 수정):
https://www.cnblogs.com/perki...
요약:
isInterrupted() 와 interrupt 방법 을 결합 하여 사용 하면 절대 다수의 업무 중단 isInterrupted, wait, sleep 등 차단 또는 연결 방법 을 사용 할 때 중단 이상 을 던 지 는데 왜 이렇게 디자인 합 니까?이것 은 스 레 드 가 특정한 원인 으로 걸 린 후에 후속 업무 가 아직 실행 되 지 않 았 다 면 스 레 드 를 강제 중단 하면 예측 할 수 없 는 결 과 를 초래 할 수 있 습 니 다 (예 를 들 어 파일 이 절반 을 기록 한 것). 스 레 드 를 중단 하려 면 catch 블록 에서 다시 호출 할 수 있 습 니 다 join 방법 interrupt 과 interrupted() 방법 은 모두 호출 된 isInterrupted() 들 어 오 는 private native boolean isInterrupted(boolean ClearInterrupted) 의 값 에 따라 중단 표지 위치 이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.