문제

어떻게 죽이나요? java.lang.Thread 자바에서?

도움이 되었습니까?

해결책

이것 좀 봐 왜 그들이 더 이상 사용되지 않는지에 대한 실 Thread.stop(). 왜 이것이 나쁜 방법 이었는지, 그리고 일반적으로 스레드를 안전하게 중지하기 위해 무엇을 해야하는지에 대해 자세히 설명합니다.

그들이 추천하는 방식은 공유 변수를 배경 스레드를 멈추도록 요구하는 플래그로 사용하는 것입니다. 그런 다음이 변수는 스레드 종료를 요청하는 다른 객체에 의해 설정 될 수 있습니다.

다른 팁

일반적으로 당신은 ..

당신은 그것을 사용하고있는 모든 것을 방해하도록 요청합니다. Thread.interrupt () (Javadoc Link)

왜 Javadoc에 있는지에 대한 좋은 설명 여기 (Java Technote Link)

자바에서 실은 죽지 않지만 실의 멈추는 것은 협력적인 방법. 스레드가 종료되도록 요청하고 스레드가 우아하게 종료 될 수 있습니다.

종종 a volatile boolean 스레드가 해당 값으로 설정되면 주기적으로 검사하고 종료되는 필드가 사용됩니다.

그렇지 않을 것입니다 a boolean 스레드가 있어야하는지 확인합니다 끝내다. 사용하는 경우 volatile 필드 수정 자로, 이것은 신뢰할 수 있지만 코드가 더 복잡해지면 대신 내부에 다른 차단 방법을 사용하기 위해 while 루프, 코드가 발생할 수 있습니다. 종료되지 않습니다 전혀 또는 적어도 더 오래 걸립니다 당신이 원하는대로.

특정 차단 라이브러리 방법은 중단을 지원합니다.

모든 스레드에는 이미 부울 깃발이 있습니다 중단 상태 그리고 당신은 그것을 사용해야합니다. 다음과 같이 구현할 수 있습니다.

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

소스 코드에서 조정되었습니다 실제로 Java 동시성. 이후 cancel() 메소드는 공개적입니다. 다른 스레드가 원하는 대로이 메소드를 호출하도록 할 수 있습니다.

한 가지 방법은 클래스 변수를 설정하고 센티넬로 사용하는 것입니다.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

위의 예에서 외부 클래스 변수, 즉 flag = true를 설정하십시오. 스레드를 '킬'하도록 false로 설정하십시오.

당신이 할 수있는 방법이 있습니다. 그러나 당신이 그것을 사용해야한다면, 당신은 나쁜 프로그래머이거나 나쁜 프로그래머가 작성한 코드를 사용하고 있습니다. 따라서, 당신은 나쁜 프로그래머가되는 것을 멈추 거나이 나쁜 코드 사용을 중단하는 것에 대해 생각해야합니다. 이 솔루션은 다른 방법이없는 상황에만 해당됩니다.

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );

축적 된 의견을 바탕으로 몇 가지 관찰을 추가하고 싶습니다.

  1. 보안 관리자가 허용하면 Thread.Stop ()이 스레드를 중지합니다.
  2. Thread.stop ()는 위험합니다. JEE 환경에서 일하고 있고 호출되는 코드를 제어 할 수없는 경우 필요할 수 있습니다.
  3. 컨테이너 작업자 스레드를 중지해서는 안됩니다. 매달려있는 경향이있는 코드를 실행하려면 (신중하게) 새 데몬 스레드를 시작하여 모니터링하여 필요한 경우 죽입니다.
  4. stop ()에서 새 threaddeath 오류를 만듭니다. 부름 스레드를 한 다음 해당 오류가 표적 실. 따라서 스택 추적은 일반적으로 무가치합니다.
  5. JRE 6에서 stop ()는 보안 관리자와 확인한 다음 stop0 ()을 호출하는 stop1 ()을 호출합니다. stop0 ()는 기본 코드입니다.

나는 투표 할 것이다 Thread.stop().

예를 들어 네트워크 요청과 같은 오래 지속되는 작업이 있습니다. 아마도 당신은 응답을 기다리고 있지만 시간이 걸릴 수 있고 사용자는 다른 UI로 탐색했습니다. 이 대기 스레드는 이제 a) 쓸모없는 b) 잠재적 인 문제가 될 때 결과가 나올 때 완전히 쓸모없고 오류가 발생할 수있는 콜백을 트리거 할 것이기 때문입니다.

그 모든 것과 그는 CPU 강렬한 응답 처리를 수행 할 수 있습니다. 그리고 당신은 개발자로서 당신이 던질 수 없기 때문에 멈출 수 없습니다. if (Thread.currentThread().isInterrupted()) 모든 코드의 줄.

따라서 스레드를 강력하게 멈출 수 없다는 것은 이상합니다.

문제는 다소 모호합니다. "원할 때 스레드가 실행되지 않도록 프로그램을 작성하는 방법"을 의미한다면 다양한 다른 응답이 도움이 될 것입니다. 그러나 "서버를 사용하여 긴급 상황이 있고 지금 당장 다시 시작할 수 없으며 죽기 위해 특정 스레드가 필요합니다. jstack.

이 목적을 위해 내가 만든 것입니다 Jkillthread. 사용에 대한 지침을 참조하십시오.

물론 당신이 어떤 종류의 완전하지 않은 코드를 실행하는 경우가 있습니다. (저는 Java 환경에서 업로드 된 스크립트를 실행할 수 있도록하여 개인적으로 이것을 가지고 있습니다. 예, 모든 곳에서 보안 알람 벨이 울리는 것이 있지만 응용 프로그램의 일부입니다.)이 불행한 경우에는 먼저 스크립트 작가에게 물어 보면서 희망이 있습니다. 어떤 종류의 부울 실행/실행되지 않는 신호를 존중합니다. 당신의 유일한 괜찮은 실패 안전은 시간 초과보다 더 오래 실행되면 스레드에서 정지 메소드를 호출하는 것입니다.

그러나 코드가 Threaddeath 오류 (또는 명시 적으로 던지는 예외)를 포착 할 수 있기 때문에 이것은 "괜찮은"것입니다. 왜냐하면 신사 스레드가해야 할 것처럼 재검사하지 않기 때문입니다. 따라서 결론은 Afaia입니다. 절대 실패 안전은 없습니다.

실을 우아하게 죽일 방법이 없습니다.

스레드를 방해하려고 시도 할 수 있습니다. 하나의 커먼즈 전략은 독약을 사용하여 스레드를 메시지로 메시지를 보내는 것입니다.

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = “stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

http://anandsekar.github.io/cancel-support-for-threads/

일반적으로 스레드를 죽이거나 멈추거나 방해하지 않습니다 (또는 Wheter는 IT가 중단되는지 확인) 그러나 자연스럽게 종료하십시오.

이건 간단하다. (휘발성) 부울 변수 내부 run () 메소드와 함께 모든 루프를 사용하여 스레드의 활동을 제어 할 수 있습니다. 활성 스레드에서 기본 스레드로 돌아와서 중지 할 수도 있습니다.

이런 식으로 당신은 실을 우아하게 죽입니다 :).

갑작스런 스레드 종료 시도는 잘 알려진 나쁜 프로그래밍 관행과 응용 프로그램 설계 불량의 증거입니다. 멀티 스레드 애플리케이션의 모든 스레드는 명시 적으로 그리고 암시 적으로 동일한 프로세스 상태를 공유하고 서로 협력하여 일관성을 유지하도록 강요했습니다. 그렇지 않으면 응용 프로그램이 실제로 진단하기 어려운 버그가 발생합니다. 따라서 신중하고 명확한 애플리케이션 설계를 통해 이러한 일관성을 보장하는 것은 개발자의 책임입니다.

제어 스레드 종단에 대한 두 가지 주요 솔루션이 있습니다.

  • 공유 휘발성 플래그 사용
  • thread.interrupt () 및 thread.interrupted () 메소드 쌍의 사용

갑작스런 스레드 종료와 관련된 문제에 대한 양호하고 자세한 설명뿐만 아니라 제어 된 스레드 종료에 대한 잘못된 및 올바른 솔루션의 예는 여기에서 찾을 수 있습니다.

https://www.securecoding.cert.org/confluence/display/java/thi05-j.+do+not+use+thread.stop%29+ Trerminate+threads

다음은 주제에 대한 몇 가지 좋은 독서입니다.

InterruptedException으로 무엇을합니까?

스레드를 깨끗하게 종료합니다

'실을 죽이는 것'은 사용하기에 적합한 문구가 아닙니다. 다음은 Will에서 스레드의 우아한 완료/출구를 구현할 수있는 한 가지 방법입니다.

내가 사용한 달리기 가능 :

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

트리거링 클래스 :

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}

안드로이드에서 인터럽트가 작동하지 않았 으므로이 방법을 사용하여 완벽하게 작동합니다.

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top