Java에서 스레드를 종료하려면 어떻게 해야 합니까?
?java.lang.Thread★★★★★★★★★★★★★★★★★?
이 스레드 by Sun을 참조해 주세요.이것이 왜 나쁜 방법인지, 그리고 일반적으로 스레드를 안전하게 멈추기 위해 무엇을 해야 하는지에 대해 자세히 설명합니다.
이들은 공유 변수를 백그라운드 스레드의 정지를 요구하는 플래그로 사용하는 것을 권장합니다.이 변수는 스레드 종료를 요청하는 다른 개체에 의해 설정될 수 있습니다.
일반적으로 당신은..
스레드를 사용하여 수행하는 모든 작업을 중단하도록 요청합니다.interrupt() (adoc 링크)
이유는 여기 javadoc에 있습니다(Java technote 링크).
Java에서는 스레드는 종료되지 않지만 스레드의 정지는 협조적인 방법으로 이루어집니다.스레드 종료를 요구받으면 스레드는 정상적으로 셧다운됩니다.
경우, " " "volatile boolean필드는 스레드가 대응하는 값으로 설정되었을 때 정기적으로 체크하고 종료하는 필드입니다.
사용하지 않을 것입니다.boolean스레드가 종료되는지 여부를 확인합니다.사용하시는 경우volatile수 있지만, 할 수식어, 수식어, 수식어, 수식어, 수식어, 수식어, 수식어를 사용합니다.while루프가 발생할 수 있습니다.코드가 전혀 종료되지 않거나 최소한 원하는 만큼 시간이 걸릴 수 있습니다.
특정 차단 라이브러리 메서드는 중단을 지원합니다.
모든 스레드에 이미 부울 플래그 인터럽트 상태가 있으므로 이를 사용해야 합니다.다음과 같이 구현할 수 있습니다.
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Java Concurrency in Practice에서 수정된 소스 코드입니다.그 이후로는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() );
나는 축적된 코멘트를 바탕으로 몇 가지 관찰을 덧붙이고 싶다.
Thread.stop()는 보안 하는 경우 합니다.Thread.stop()위험합니다.JEE 환경에서 작업하고 있고 호출되는 코드를 제어할 수 없는 경우 필요할 수 있습니다.「 Thread . stop 」를 참조해 주세요.- 컨테이너 작업자 스레드를 중지하지 마십시오.행하기 쉬운 코드를 실행하는 경우는, 새로운 데몬 스레드를 기동해 모니터 해, 필요에 따라서 종료합니다.
stop()「」를 한다.ThreadDeathError에러를 발신측 스레드로 송신하고, 그 에러를 타겟스레드에 송신합니다.따라서 스택 트레이스는 일반적으로 가치가 없습니다.- 6에서는 JRE 6의
stop()하고 나서 "Security Manager"를 호출합니다.stop1()를 호출합니다.stop0()stop0()네이티브 코드입니다. - 13 Java 13 재재 。
Thread.stop()( () 제거되지 않았습니다만,Thread.stop(Throwable)Java 11에서 삭제되었습니다.(메일링 리스트, JDK-8204243)
는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★Thread.stop().
예를 들어 네트워크 요구와 같은 장시간 지속되는 작업이 있습니다.아마 응답을 기다리고 있을 것입니다만, 시간이 걸려, 유저가 다른 UI로 이동합니다.이 대기 스레드는 a) 결과를 얻을 때 완전히 무용지물이 되고 오류가 발생할 수 있는 콜백을 트리거하기 때문에 b) 잠재적인 문제가 됩니다.
이 모든 것은 CPU 부하가 높은 응답 처리를 할 수 있습니다.그것을. 은 그것을 수 없기 때문입니다.if (Thread.currentThread().isInterrupted())행이 표시됩니다.
실타래를 강제로 멈출 수 없다는 건 이상해요
그 질문은 다소 모호하다."원할 때 스레드가 실행을 중지하도록 프로그램을 작성하려면 어떻게 해야 합니까?"를 의미했다면 다른 다양한 응답이 도움이 될 것입니다., 「할 수 의 스레드를 있기 때문에,이 일어나도 상관없습니다라고 하는 에는, 감시 합니다.jstack.
이를 위해 jkillthread를 만들었습니다.사용방법에 대해서는, 을 참조해 주세요.
물론 완전히 신뢰할 수 없는 코드를 실행하고 있는 경우도 있습니다.(개인적으로는 업로드된 스크립트를 Java 환경에서 실행할 수 있도록 함으로써 이 기능을 갖게 되었습니다.네, 어디에서나 보안 경보 벨이 울리고 있지만, 이는 애플리케이션의 일부입니다.)이 불행한 예에서는 우선 스크립트 작성자에게 부울런/런하지 않는 신호를 존중해 달라고 하는 것으로, 단지 희망에 차 있을 뿐입니다.적절한 Fail Safe는, 예를 들면, 타임 아웃보다 오래 실행되는 경우, 스레드의 정지 메서드를 호출하는 것 뿐입니다.
그러나 이는 절대적인 것이 아니라 단지 "사기"일 뿐이며, 이는 코드가 ThreadDeath 오류(또는 당신이 명시적으로 던지는 예외)를 포착하고 신사적인 스레드처럼 다시 던지지 않을 수 있기 때문입니다.결론은 AFA입니다.IA 절대적인 장애 안전은 없습니다.
우아하게 실을 끊을 수 있는 방법은 없다.
스레드를 중단하려고 시도할 수 있습니다. 일반적인 전략 중 하나는 독약을 사용하여 스레드가 스스로를 멈추도록 메시지를 보내는 것입니다.
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/
'실타래 죽이기'는 올바른 표현이 아니다.다음은 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");
}
}
일반적으로 스레드는 종료, 정지 또는 인터럽트하지 않고(또는 인터럽트()를 체크하지 않고 자연스럽게 종료합니다.
그것은 간단하다.run() 메서드 내의 (휘발성) 부울 변수와 함께 임의의 루프를 사용하여 스레드의 액티비티를 제어할 수 있습니다.또한 활성 스레드에서 메인 스레드로 돌아가 이를 중지할 수도 있습니다.
이렇게 하면 스레드를 정상적으로 절단할 수 있습니다. : ).
갑작스런 스레드 종료 시도는 잘 알려진 잘못된 프로그래밍 관행이며 애플리케이션 설계가 잘못되었다는 증거입니다.멀티스레드 어플리케이션의 모든 스레드는 명시적으로 암묵적으로 동일한 프로세스 상태를 공유하며 일관성을 유지하기 위해 서로 협력해야 합니다.그렇지 않으면 어플리케이션에서 버그가 발생하기 쉽고 진단이 매우 어렵습니다.따라서 신중하고 명확한 애플리케이션 설계를 통해 이러한 일관성을 보장하는 것은 개발자의 책임입니다.
제어된 스레드 종단에 대한 두 가지 주요 올바른 솔루션이 있습니다.
- 공유 휘발성 플래그 사용
- 스레드 쌍의 사용.인터럽트()와 스레드.interrupted() 메서드.
갑작스런 스레드 종료와 관련된 문제에 대한 적절하고 자세한 설명 및 제어된 스레드 종료에 대한 잘못된 올바른 해결책의 예는 다음과 같습니다.
다음은 이 주제에 대한 몇 가지 유용한 내용입니다.
Android에서 작업을 중단하지 않았기 때문에 이 방법을 사용하여 완벽하게 작동합니다.
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;
}
Thread.stop은 권장되지 않습니다.Java에서 스레드를 정지하려면 어떻게 해야 합니까?
항상 인터럽트 방법 및 미래 방식을 사용하여 취소 요청
- 작업이 인터럽트 신호에 응답하는 경우(예: 블로킹큐가 방식을 취합니다).
Callable < String > callable = new Callable < String > () {
@Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
- 태스크가 인터럽트 신호에 응답하지 않는 경우.태스크가 소켓 I/O를 실행하여 인터럽트 신호에 응답하지 않으므로 위의 접근 방식을 사용하여 태스크를 중단하지 않는다고 가정하면, 향후 타임아웃하지만 최종 블록에서의 취소는 효과가 없습니다. 스레드는 소켓을 계속 수신합니다.소켓을 닫거나 연결 시 콜 클로즈 방식을 풀별로 구현할 수 있습니다.
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}
자바에서 15년 이상 발전해 온 후 세상에 하고 싶은 말이 하나 있다.
권장하지 않다Thread.stop()그리고 그 사용에 대한 성스러운 싸움은 단지 또 다른 나쁜 습관일 뿐이고 디자인상의 결함이 불행하게도 현실이 되었다.(예를 들어, 에 대해 이야기하고 싶다.Serializable인터페이스)
실타래를 죽이면 사물이 일관되지 않은 상태로 남을 수 있다는 사실에 싸움이 집중되고 있다.그래서?멀티스레드 프로그래밍에 오신 것을 환영합니다.당신은 프로그래머이고, 당신이 무엇을 하고 있는지 알아야 합니다. 그리고 그렇습니다.스레드를 종료하면 오브젝트가 일관되지 않은 상태가 될 수 있습니다.걱정이 되신다면flag실타래가 우아하게 끊어지도록 놔두어라. 을 사용법
「...」라고 입력하면, 「...」thread.stop()당신은 당신의 코드를 보는 모든 사람들에게 살해당할 수 있습니다. 이렇게 해서 써야 요.flag콜, 콜, 콜interrupt(), 표시if(!flag)루프가 전혀 없기 때문에 코드 주위에 있는 모든 것을 사용하고, 마지막으로 외부 콜의 실행에 사용하고 있는 서드파티 라이브러리가 올바르게 쓰여져 있고, 이 라이브러리가 처리되지 않도록 기도합니다.InterruptException부적절하게
언급URL : https://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java
'programing' 카테고리의 다른 글
| Vue2.js - 오브젝트 내의 메서드를 호출하여 콜백합니다(이 문제). (0) | 2022.07.08 |
|---|---|
| Java 글로벌 변수 (0) | 2022.07.08 |
| Vuex는 API 오류 알림을 처리하는 방법을 알려 주시겠습니까? (0) | 2022.07.08 |
| Vuex에서 서로 변환하지 않고 동일한 개체를 두 변수로 복사하려면 어떻게 해야 합니까? (0) | 2022.07.08 |
| Android Get Current 타임스탬프? (0) | 2022.07.08 |