Java 스레드를 정상적으로 중지하는 방법은 무엇입니까?
스레드를 작성했는데 실행하는 데 너무 많은 시간이 걸리고 완전히 완료되지 않은 것 같습니다. 스레드를 우아하게 중지하고 싶습니다. 도움이 필요하세요?
좋은의 그것을 할 방법은 것입니다 run()
a로 보호 스레드의 boolean
변수를과하도록 설정 true
하면, 같은 것을 중지 할 때 외부에서 :
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
옛날에 stop()
방법이 존재했지만 문서에 나와있는대로
이 방법은 본질적으로 안전하지 않습니다. Thread.stop으로 스레드를 중지하면 잠긴 모든 모니터의 잠금이 해제됩니다 (스택 위로 전파되는 확인되지 않은 ThreadDeath 예외의 자연스러운 결과로). 이러한 모니터에 의해 이전에 보호 된 개체가 일관성없는 상태에있는 경우 손상된 개체가 다른 스레드에 표시되어 잠재적으로 임의 동작이 발생할 수 있습니다.
그래서 경비원이 있어야합니다 ..
스레드를 중지하기 위해 플래그를 사용하는 것의 나쁜 점은 스레드가 대기 중이거나 대기 중이면 대기 / 수면이 완료 될 때까지 기다려야한다는 것입니다. 스레드에서 인터럽트 메소드를 호출하면 InterruptedException과 함께 wait 또는 sleep 호출이 종료됩니다.
(플래그 접근 방식에 대한 두 번째 나쁜 부분은 대부분의 사소한 코드가 java.util.concurrent와 같은 라이브러리를 사용한다는 것입니다. 클래스는 특히 인터럽트를 사용하여 취소하도록 설계되었습니다. 전달 된 작업에서 손으로 굴린 플래그를 사용하려고합니다. Executir로 들어가는 것은 어색 할 것입니다.)
interrupt () 호출은 또한 종료 여부를 확인하기위한 플래그로 사용할 수있는 인터럽트 된 속성을 설정합니다 (스레드가 대기 중이거나 휴면 상태가 아닌 경우).
스레드의 실행 메소드를 작성하여 스레드가 수행하는 루프 로직 외부에서 InterruptedException이 포착되도록하거나 루프 내에서 예외를 포착하고 예외를 발생시키는 호출에 가깝게 할 수 있습니다. InterruptedException은 스레드가 인터럽트되었다는 사실을 추적하지 않도록합니다. 인터럽트 된 스레드는 여전히 제어를 유지하고 자체 조건으로 처리를 완료 할 수 있습니다.
어떤 이유로 중간에 수면이있는 증분 작업을 수행하는 작업자 스레드를 작성하고 해당 증분에 대한 나머지 작업을 수행하지 않고 처리를 종료하기 위해 수면을 종료하고 싶지 않다고 가정 해 보겠습니다. 증분 사이에 있으면 종료됩니다.
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
다음은 예제 코드를 포함하여 유사한 질문에 대한 답변입니다.
다른 스레드에서 스레드를 죽이면 안됩니다. 상당히 나쁜 습관으로 간주됩니다. 그러나 여러 가지 방법이 있습니다. return
스레드의 run
메서드 에서 문을 사용할 수 있습니다 . 또는 스레드가 이미 중단되었는지 확인한 다음 작업을 취소 할 수 있습니다. Fe :
while (!isInterrupted()) {
// doStuff
}
stop
어딘가에 휘발성 부울을 만드십시오 . 그런 다음 스레드에서 실행되는 코드에서 정기적으로
if (stop) // end gracefully by breaking out of loop or whatever
스레드를 중지하려면로 설정 stop
하십시오 true
.
이런 식으로 수동으로해야한다고 생각합니다. 결국, 스레드에서 실행되는 코드 만이 우아하고 비정상적인 것을 알 수 있습니다.
스레드에 중지 메시지를 보내야하며 메시지가 수신되면 스레드 자체가 조치를 취해야합니다. 장기 실행 작업이 루프 내부에 있으면 매우 쉽습니다.
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
For a thread to stop itself, no one seems to have mentioned (mis)using exception:
abstract class SelfStoppingThread extends Thread {
@Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
A subclass just need to override doRun() normally as you would with a Thread, and call stopSelf() whenever it feels like it wants to stop. IMO it feels cleaner than using a flag in a while loop.
참고URL : https://stackoverflow.com/questions/3194545/how-to-stop-a-java-thread-gracefully
'code' 카테고리의 다른 글
Visual Studio가 설치되지 않은 컴퓨터에서 FUSLOGVW.EXE 사용 (0) | 2020.11.18 |
---|---|
명령 줄에서 WAR의 클래스를 어떻게 실행합니까? (0) | 2020.11.18 |
스트리밍 멀티 프로세서, 블록 및 스레드 (CUDA) (0) | 2020.11.18 |
Redis에서 세트를 비우거나 삭제 하시겠습니까? (0) | 2020.11.18 |
데이터 폴더의 URI로 카메라 결과를 얻는 방법은 무엇입니까? (0) | 2020.11.18 |