[android] Android-스레드를 중지하는 가장 좋고 안전한 방법

Android에서 스레드를 중지하는 가장 좋은 방법을 알고 싶습니다. AsyncTask대신 사용할 수 있고 cancel()방법 이 있다는 것을 알고 있습니다 . Thread내 상황에서 s 를 사용해야 합니다. 내가 사용하는 방법은 다음과 같습니다 Thread.

Runnable runnable = new Runnable() {
        @Override
        public void run() {
            //doing some work
        }
    };
new Thread(runnable).start();

그렇다면 스레드를 중지하는 가장 좋은 방법이 무엇인지 아는 사람이 있습니까?



답변

스레드 지원 인터럽트를 만들어야합니다. 기본적으로 yourThread.interrupt()스레드를 중지하기 위해 호출 할 수 있으며 run () 메서드에서 주기적으로 상태를 확인해야합니다.Thread.interrupted()

여기에 좋은 튜토리얼이 있습니다 .


답변

이 상황은 표준 Java와 전혀 다르지 않습니다. 표준 방법을 사용하여 스레드를 중지 할 수 있습니다.

class WorkerThread extends Thread {
    volatile boolean running = true;

    public void run() {
        // Do work...
        if (!running) return;
        //Continue doing the work
    }
}

주요 아이디어는 수시로 필드의 가치를 확인하는 것입니다. 스레드를 중지해야하는 경우 runningfalse로 설정 합니다. 또한 Chris가 지적했듯이 중단 메커니즘을 사용할 수 있습니다.

그건 그렇고, AsyncTask를 사용할 때 접근 방식은 크게 다르지 않습니다. 유일한 차이점은 isCancel()특수 필드를 갖는 대신 작업에서 메서드 를 호출해야한다는 것입니다 . 를 호출 cancel(true)하지만이 메커니즘을 구현하지 않으면 스레드가 여전히 저절로 중지되지 않고 끝까지 실행됩니다.


답변

Android에서는 일반 Java 환경과 동일한 규칙이 적용됩니다. Java에서 스레드는 종료되지 않지만 스레드 중지는 협력적인 방식으로 수행됩니다 . 스레드는 종료하도록 요청되고 스레드는 정상적으로 종료 될 수 있습니다.

종종 volatile boolean스레드가 해당 값으로 설정 될 때 주기적으로 확인하고 종료 하는 필드가 사용됩니다.

나는 스레드가 종료 되어야하는지 여부를 확인 하기 위해 사용 하지 않을 것 입니다. 필드 수정 자로 사용하면 안정적으로 작동하지만 코드가 더 복잡해지면 루프 내에서 다른 차단 방법을 대신 사용 하기 때문에 코드가 전혀 종료되지 않거나 최소한 시간이 더 오래 걸릴 수 있습니다. 아마도 원한다.booleanvolatilewhile

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

모든 스레드에는 이미 부울 플래그 인터럽트 상태 가 있으므로 이를 사용해야합니다. 다음과 같이 구현할 수 있습니다.

public void run() {

   try {
      while(!Thread.currentThread().isInterrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }

}

public void cancel() { interrupt(); }

Java Concurrency in Practice 에서 가져온 소스 코드 입니다. cancel()메서드가 공용 이므로 원하는대로 다른 스레드가이 메서드를 호출하도록 할 수 있습니다.

interrupted현재 스레드의 중단 된 상태를 지우는 이름 이 잘못된 정적 메서드도 있습니다 .


답변

Thread.stop()스레드를 중지하는 데 사용 될 수있는 방법은 사용되지 않습니다; 자세한 내용은 다음을 참조하십시오. Thread.stop, Thread.suspend 및 Thread.resume이 더 이상 사용되지 않는 이유는 무엇입니까? .

가장 좋은 방법은 스레드 자체가 참조하는 변수를 가지고 변수가 특정 값과 같으면 자발적으로 종료하는 것입니다. 그런 다음 스레드가 종료되기를 원할 때 코드 내에서 변수를 조작합니다. 물론 AsyncTask대신 사용할 수도 있습니다 .


답변

현재 그리고 안타깝게도 스레드를 중지하기 위해 아무것도 할 수 없습니다 ….

Matt의 대답에 무언가를 추가하면 우리가 호출 할 수는 interrupt()있지만 스레드를 중지하지는 않습니다. 시스템이 스레드를 중지하려고 할 때 시스템에 스레드를 중지하도록 지시합니다. 휴식은 시스템에 의해 이루어지며을 호출하여 확인할 수 있습니다 interrupted().

[ps : 정말 같이 가신다면 interrupt()전화를 걸어 잠깐자는 실험을 해보 시죠 interrupt()]


답변

이렇게 해봐

Thread thread = new Thread() {
    @Override
    public void run() {
        Looper.prepare();
        while(true){
            Log.d("Current Thread", "Running");
            try{
               Thread.sleep(1000);
            }catch(Exeption exception){ }
        }
    }
};

thread.start();
thread.interrupt();


답변

스레드를 중지하는 데 선호되는 두 가지 방법이 있습니다.

  1. 휘발성 부울 변수를 만들고 그 값을 false로 변경하고 스레드 내부를 확인합니다.

    volatile isRunning = false;
    
    public void run() {
    if(!isRunning) {return;}
    
    }
    
  2. 또는 스레드 내부에서받을 수있는 interrupt () 메서드를 사용할 수 있습니다.

    SomeThread.interrupt();
    
    public void run() {
    if(Thread.currentThread.isInterrupted()) {return;}
     }