JAVA 멀티스레드 인터럽트 메커니즘stop(), interrupted(), isInterrupted()

소개
본고는 JAVA 다중 스레드의 인터럽트 메커니즘에 대한 지식을 기록합니다.주로stop방법,interrupted()와 isInterrupted()방법의 차이를 설명하고 원본 코드의 실현에서 간단하게 분석한다.
JAVA에는 실행 중인 스레드를 종료하는 3가지 방법이 있습니다.
① 루틴이 정상적으로 종료됨, 즉run() 방법이 실행됨
②Thread 클래스의 stop() 방법을 사용하여 스레드를 강제로 종료합니다.하지만 stop () 방법은 이미 기한이 지났습니다. 사용을 추천하지 않습니다.
③ 인터럽트 메커니즘 사용
루틴이 정상적으로 종료되는 것은 아무것도 없습니다. 중단 메커니즘은 아래에 상세하게 소개합니다. 먼저stop() 방법의 원본 코드를 보십시오. 관건은 원본 코드의 주석입니다.이것은 왜 stop () 가 안전하지 않은지, stop () 방법이 멈추는 것이 어떤 라인인지 설명합니다.

/**
* Forces the thread to stop executing.
* <p>
* If there is a security manager installed, its <code>checkAccess</code>
* method is called with <code>this</code>
* as its argument. This may result in a
* <code>SecurityException</code> being raised (in the current thread).
* <p>
* If this thread is different from the current thread (that is, the current
* thread is trying to stop a thread other than itself), the
* security manager's <code>checkPermission</code> method (with a
* <code>RuntimePermission("stopThread")</code> argument) is called in
* addition.
* Again, this may result in throwing a
* <code>SecurityException</code> (in the current thread).
* <p>
* The thread represented by this thread is forced to stop whatever
* it is doing abnormally and to throw a newly created
* <code>ThreadDeath</code> object as an exception.
* <p>
* It is permitted to stop a thread that has not yet been started.
* If the thread is eventually started, it immediately terminates.
* <p>
* An application should not normally try to catch
* <code>ThreadDeath</code> unless it must do some extraordinary
* cleanup operation (note that the throwing of
* <code>ThreadDeath</code> causes <code>finally</code> clauses of
* <code>try</code> statements to be executed before the thread
* officially dies). If a <code>catch</code> clause catches a
* <code>ThreadDeath</code> object, it is important to rethrow the
* object so that the thread actually dies.
* <p>
* The top-level error handler that reacts to otherwise uncaught
* exceptions does not print out a message or otherwise notify the
* application if the uncaught exception is an instance of
* <code>ThreadDeath</code>.
*
* @exception SecurityException if the current thread cannot
* modify this thread.
* @see #interrupt()
* @see #checkAccess()
* @see #run()
* @see #start()
* @see ThreadDeath
* @see ThreadGroup#uncaughtException(Thread,Throwable)
* @see SecurityManager#checkAccess(Thread)
* @see SecurityManager#checkPermission
* @deprecated This method is inherently unsafe. Stopping a thread with
* Thread.stop causes it to unlock all of the monitors that it
* has locked (as a natural consequence of the unchecked
* <code>ThreadDeath</code> exception propagating up the stack). If
* any of the objects previously protected by these monitors were in
* an inconsistent state, the damaged objects become visible to
* other threads, potentially resulting in arbitrary behavior. Many
* uses of <code>stop</code> should be replaced by code that simply
* modifies some variable to indicate that the target thread should
* stop running. The target thread should check this variable
* regularly, and return from its run method in an orderly fashion
* if the variable indicates that it is to stop running. If the
* target thread waits for long periods (on a condition variable,
* for example), the <code>interrupt</code> method should be used to
* interrupt the wait.
* For more information, see
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated
public final void stop() {
stop(new ThreadDeath());
}
위에서 설명한 바와 같이 9행에서 16행까지는stop () 방법이 다른 라인을 멈출 수 있음을 나타낸다.실행thread.stop () 방법 이 문장의 라인을 현재 라인이라고 하고,'다른 라인'은thread를 호출합니다.stop () 방법의 대상thread가 대표하는 라인입니다.
예:

public static void main(String[] args) {
MyThread thread = new MyThread...
//.....
thread.stop();
//....
}
main 방법에서 현재 라인은 main 라인입니다.이것은 네 번째 줄로 실행됩니다. "다른 스레드"thread를 멈추려고 합니다. 이 다른 스레드는 MyThread 클래스 new의thread 대상이 표시하는 스레드입니다.
21줄에서 23줄까지는 아직 시작하지 않은 라인을 멈출 수 있음을 나타낸다.그 효과는 이 라인이 시작되면 바로 끝난다는 것이다.
48행 이후의 주석은 왜 stop () 방법이 사용되지 않는지 깊이 있게 나타낸다!왜 안전하지 않아요?
예를 들어threadA 라인은 모니터를 가지고 있는데 이런 모니터는 일부 임계 자원, 예를 들어 은행의 이체 금액을 보호하는 것을 책임진다.이체 중,main 라인은threadA를 호출합니다.stop () 메서드.그 결과 모니터가 방출되고 보호된 자원(이체 금액)이 일치하지 않을 가능성이 높다.예를 들어 A 계좌는 100 감소했지만 B 계좌는 100 증가하지 않았다
둘째, 인터럽트 메커니즘
JAVA에서 인터럽트 메커니즘을 정확하게 사용하는 방법은 너무 많다.interrupted () 방법과 isInterrupted () 방법은 현재 라인의 중단 상태를 반영합니다.
①interrupted()

/**
* Tests whether the current thread has been interrupted. The
* <i>interrupted status</i> of the thread is cleared by this method. In
* other words, if this method were to be called twice in succession, the
* second call would return false (unless the current thread were
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if the current thread has been interrupted;
* <code>false</code> otherwise.
* @see #isInterrupted()
* @revised .
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
원본 코드의 주석에서 알 수 있듯이, 이것은 현재 라인 (currentthread) 의 중단 상태를 테스트하고, 이 방법은 중단 상태를 제거합니다.
②isInterrupted()

/**
* Tests whether this thread has been interrupted. The <i>interrupted
* status</i> of the thread is unaffected by this method.
*
* <p>A thread interruption ignored because a thread was not alive
* at the time of the interrupt will be reflected by this method
* returning false.
*
* @return <code>true</code> if this thread has been interrupted;
* <code>false</code> otherwise.
* @see #interrupted()
* @revised .
*/
public boolean isInterrupted() {
return isInterrupted(false);
}
원본 주석에서 알 수 있듯이 isInterrupted () 방법은 중단 상태를 지우지 않습니다.
③ interrupted () 방법과 isInterrupted () 방법의 차이
원본 코드에서 알 수 있듯이 이 두 가지 방법은 모두 호출된 isInterrupted(boolean ClearInterrupted)입니다. 단지 하나의 테이프의 매개 변수는true이고, 다른 테이프의 매개 변수는false입니다.

/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
따라서 첫 번째 차이점은 하나는 중단 표지 위치를 지우고 다른 하나는 중단 표지 위치를 지우지 않는다는 것이다.
원본 코드를 다시 분석하면 두 번째 차이점은 return 문장에 있다.

public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/************************/
public boolean isInterrupted() {
return isInterrupted(false);
}
interrupted () 테스트는 현재 라인의 중단 상태입니다.isInterrupted () 테스트는 이 방법을 호출하는 대상이 표시하는 라인입니다.하나는 정적 방법 (현재 라인의 중단 상태를 테스트하는 것) 이고, 하나는 실례 방법 (실례 대상이 표시하는 라인의 중단 상태를 테스트하는 것) 이다.
다음은 구체적인 예로 이 차이를 더욱 진일보하게 밝히겠습니다.
다음과 같은 사용자 정의 스레드 클래스가 있습니다.

public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = ; i < ; i++) {
System.out.println("i=" + (i + ));
}
}
}
interrupted () 메서드의 예제:

public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep();
thread.interrupt();
//Thread.currentThread().interrupt();
System.out.println(" ?="+thread.interrupted());//false
System.out.println(" ?="+thread.interrupted());//false main !!!
      //......
다섯 번째 줄은thread 라인을 시작하고, 여섯 번째는main 라인을 1초 동안 수면시켜thread 라인을 CPU로 실행할 수 있는 기회를 줍니다.
main 스레드 수면 1s 시간 후 7 줄로 복구하여thread 스레드 중단을 요청합니다.
9행 테스트 라인이 중단된 상태입니까? 여기서 테스트하는 라인은 어느 라인입니까??답은main 라인입니다.왜냐하면:
(1)interrupted () 테스트는 현재 라인의 중단 상태입니다
(2)main 라인은 9행 문장을 실행하기 때문에main 라인은 현재 라인이다
isInterrupted () 메서드의 예제:

public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep();
thread.interrupt();
System.out.println(" ?="+thread.isInterrupted());//true
여덟 번째 줄은thread 대상이 호출하는 isInterrupted () 방법입니다.따라서 테스트는thread 대상이 대표하는 라인의 중단 상태입니다.7 줄에서main 라인은thread 라인을 중단할 것을 요청하기 때문에 8 줄의 결과는:true

좋은 웹페이지 즐겨찾기