자바 : Thread.interrupted ()와 Thread.isInterrupted ()의 사용법 차이?
자바 질문 : 내가 아는 한, 스레드가 인터럽트 신호를 받았는지 여부를 스레드 내부에서 확인하는 두 가지 방법이 Thread.interrupted()
있으며 Thread.isInterrupted()
, 그리고 그들 사이의 유일한 차이점은 전자가 내부 인터럽트 플래그를 재설정한다는 것입니다.
지금까지 나는 항상 사용해 왔으며 Thread.isInterrupted()
문제가 없었습니다. 그런 다음 내가 본 대부분의 자습서에서는 Thread.interrupted()
. 그에 대한 특별한 이유가 있습니까?
interrupted()
인 static
현재 스레드 체크한다. 호출 된 객체 isInterrupted()
를 확인하는 인스턴스 메서드입니다 Thread
.
일반적인 오류는 인스턴스에서 정적 메서드를 호출하는 것입니다.
Thread myThread = ...;
if (myThread.interrupted()) {} // WRONG! This might not be checking myThread.
if (myThread.isInterrupted()) {} // Right!
또 다른 차이점은 interrupted()
현재 스레드의 상태도 지우는 것입니다. 즉, 연속으로 두 번 호출하고 두 호출 사이에 스레드가 중단되지 않으면 false
첫 번째 호출이를 반환 하더라도 두 번째 호출이 반환 true
됩니다.
Javadoc과는 당신에게이 같은 중요한 일을 말할; 자주 사용하십시오!
을 사용하는 경우 interrupted
"마지막으로 요청한 이후로 중단 된 적이 있습니까?"라는 질문이 표시됩니다.
isInterrupted
호출 한 스레드가 현재 중단되었는지 여부를 알려줍니다.
interrupted()
방법은 클래스 메소드입니다 항상 현재의 thread를 확인 하고 중단 "플래그"를 지 웁니다. 즉,에 대한 두 번째 호출 interrupted()
은을 반환 false
합니다.
isInterrupted()
방법 인스턴스 메소드이고; 호출 된 스레드의 상태를보고합니다. 또한 중단 플래그를 지우지 않습니다. 플래그가 설정되어 있으면이 메서드를 호출 한 후에도 설정된 상태로 유지됩니다.
를 둘러싼 많은 관용구가 InterruptedException
있지만 문제는 중단 된 상태를 명시 적으로 확인하는 것이 었습니다.
내 이해는 isInterrupted
(인스턴스 메서드)는 주로 로깅 및 디버깅 등에 거의 사용되지 않아야한다는 것입니다. 주어진 스레드에있는 플래그의 스냅 샷 만 제공하며 곧 만료 될 수 있습니다.
일반적인 관용구는 슬립이나 I / O 호출 차단 등으로 인해 발생 하는 무언가를 호출 하지 않는interrupted
특정 지점에서 취소 할 수있는 작업을 작성하고 있는지 확인하는 것입니다 (정적 메서드) . 플래그 세트가 표시되면 가능한 한 빨리 현재 계산을 중지하고 일찍 반환하거나 예외를 발생 시킵니다 (아마도 ).InterruptedException
InterruptedException
예를 들어 작업이 다음과 같으면
void process(Things[] things) throws InterruptedException {
for (Thing thing : things) {
thing.twiddle(); // this call throws InterruptedException
}
}
그러면 다른 작업을 수행 할 필요가 없습니다. 누군가가 Thread.interrupt
당신의 스레드를 호출 하면 현재 또는 다음 twiddle
호출 중에 a InterruptedException
가 던져지고 작업이 중지됩니다.
그러나 경우는 twiddle
않습니다 하지 던져 InterruptedException
일반적으로 중간에 중단 될 수없는 이유는 무엇입니까? 각 호출에 100ms가 걸리지 만 100ms things.length
가 될 수 있다고 가정합니다. 그런 다음 process
누군가가 호출 을 중단하려고해도 10 초 동안 차단 될 수 있으며 이는 애플리케이션에서 허용되지 않을 수 있습니다. 따라서 명시 적으로 인터럽트를 확인할 수 있습니다.
void process(Things[] things) {
if (Thread.interrupted()) {
return;
}
for (Thing thing : things) {
thing.twiddle();
}
}
여기 interrupted
에서 플래그 를 원자 적으로 확인하고 지우는 것이 왜 중요한지 알 수 있습니다 . 메시지 수신을 확인하기 위해 플래그를 사용하고 있으며, 누군가가 가능한 한 빨리 중지하도록 정중하게 요청했습니다. (이 경우 요청 후 약 100ms 이내) 이것이 현재 스레드에서 작동하는 정적 메서드 여야하는 이유도 알 수 있습니다. 주변 코드를 중지해야하는지 여부를 확인하는 컨텍스트에서만 의미가 있습니다.
물론의 호출자 process
가 완료되었다고 가정하는 경우 return
여기에 표시된대로 단순히 호출하는 것은 오해의 소지가 있습니다. 따라서 process
처리가 완료된 항목 수를 반환하거나 예외를 발생시키는 것이 더 적절할 수 있습니다.
void process(Things[] things) throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
for (Thing thing : things) {
thing.twiddle();
}
}
이 경우 호출자는 다른 사람이 중간에 처리를 중지하도록 요청했음을 알리는 (확인 된) 예외를받습니다. 일반적으로 호출자는 호출 스택에서 예외가 발생하도록해야합니다.
현재 작업을 중지 할 수 없지만 중지 요청이 들어 왔음을 알아야하는 경우 (예 : 나머지 작업을 단축하기 위해) 자신을 다시 중단 할 수도 있습니다.
void process(Things[] things) {
boolean twiddleFully = true;
if (twiddleFully && Thread.interrupted()) {
twiddleFully = false;
Thread.currentThread().interrupt();
}
for (Thing thing : things) {
thing.twiddle(twiddleFully);
}
}
여기에서 나머지 작업을 더 빠르게 처리 할 수 있지만 여전히 루프를 완료하고 호출자가 처리하기로 결정할 수 있도록 인터럽트 된 플래그를 다시 켤 수 있습니다.
Here are a couple of examples of how you might use these methods:
If you were writing your own thread pool, you might want to check the interrupted status on one of the threads that you are managing. In that case, you would call
managedThread.isInterrupted()
to check it's interrupted status.If you are writing your own InterruptedException handlers that don't immediately retrigger an equivalent exception via
Thread.currentThread().interrupt()
(for example, you might have a finally block after your exception handlers), you might want to check whether that thread that you are currently running on has been interrupted via an outside call or InterruptedException. In that case, you would check the boolean value ofThread.interrupted()
to check on the status of your current thread.
The second method is really only ever useful to me in situations where I'm afraid that someone has written an exception eater at a lower level that, by extension, has eaten an InterruptedException as well.
Thread interruption in Java is advisory. If you call Thread.interrupt() then it will set the flag and cancel any outstanding IO tasks (which will throw InterruptedException). However it is up to code that is executing in the thread to handle this. Doing so is called implementing the Thread interruption policy.
However because Thread's interrupted state is shared it is important that any such handling be Thread Safe. You don't want some other thread going off and trying to do something with the interrupted flag if you are handling it. For this reason the Thread.interrupted() flag makes this atomic so it is used when you want to say: "If this thread was interrupted then I am going to deal with it). Usually this will involve cleaning up some resources. Once you are done you should probably propogate the interrupted flag so that callers can handle it. You can do this by recalling Thread.interrupt.
interrupted() method is a static method of class thread checks the current thread and clear the interruption "flag".i.e. a second call to interrupted() will return false.
isInterrupted() method is an instance method; it reports the status of the thread on which it is invoked. it does not clear the interruption flag.
If the flag is set, it will remain set after calling this method.
Thread myThread = ...;
if (myThread.interrupted()) {} //error
Thread.interrupted()//right
if (myThread.isInterrupted()) {} // Right
This is a old question and having gone through the answers I feel that there is still some missing information. Here's my attempt to fill in that missing piece of info.
From Java 5 onwards usually you would deal with Threads only indirectly .Infact threads spawned from the java.util.Executor framework are dealt within library methods. These threads often call entities that are of blocking nature like Future.get()
. ie get()
blocks untill result is available .Now there is a overloaded form of get()
that takes a timeout value and calling that method means that the thread wants to wait for a period equal to the timeout for the get ()
to return a value ,if not that task can be cancelled via Future.cancel(). So these methods deal with interruption seriously in that as soon as they sniff a interruption , they also throw the checked InterruptionException . Hence the callers are forced to handle InterruptionException. Since they already propagate the InterruptedException which conveys the interrupted status , it makes sense for the blocking mehthods to also clear the interrupted status by calling Thread.interrupt(). Otherwise , the contract of InterruptedException is violated.
However , if you are dealing with raw threads which is ofcourse not recommnended now , you should be careful when calling the static method interrupted()
because if you call it twice in a row and the thread is not interrupted between the two calls, the second call will return false even if the first call returned true.
ReferenceURL : https://stackoverflow.com/questions/1904072/java-difference-in-usage-between-thread-interrupted-and-thread-isinterrupted
'program story' 카테고리의 다른 글
jQuery를 사용하여 전체 페이지의 HTML을 어떻게 얻습니까? (0) | 2021.01.10 |
---|---|
.htaccess는 SSL / HTTPS를 사용하여 www를 www가 아닌 사이트로 리디렉션합니다. (0) | 2021.01.10 |
뒤로 이동할 때 UITableView를 다시로드 하시겠습니까? (0) | 2021.01.10 |
LINQ를 사용하여 C #의 정렬 목록 (0) | 2021.01.10 |
OpenWrap 대 NuGet (0) | 2021.01.10 |