1. 소개
이 문서에는 JAVA 멀티스레딩의 인터럽트 메커니즘에 대한 몇 가지 지식이 기록되어 있습니다. 주로 stop 메소드, Interrupted() 및 isInterrupted() 메소드 간의 차이점과 소스 코드 구현에 대한 간단한 분석입니다.
JAVA에서는 실행 중인 스레드를 종료하는 방법이 3가지가 있습니다
①스레드가 정상적으로 종료됩니다. 즉, run() 메소드가 실행되었습니다.
②스레드에서 stop을 사용합니다. class() 메소드는 스레드를 강제로 종료합니다. 그러나 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() 메서드를 호출하는 객체 스레드가 나타내는 스레드입니다.
예:
public static void main(String[] args) { MyThread thread = new MyThread... //..... thread.stop(); //.... }
메인 메소드에서는 현재 스레드가 메인 스레드입니다. 4행까지 실행되며 "다른 스레드 "thread"를 중지하려고 합니다. 이 다른 스레드는 새 MyThread 클래스의 스레드 객체로 표시되는 스레드입니다.
21~23행은 중지할 수 있음을 나타냅니다. 아직 시작되지 않은 스레드의 효과는 스레드가 시작되면 즉시 종료된다는 것입니다.
의 48행 이후의 주석은 stop() 메소드가 더 이상 사용되지 않는 이유를 근본적으로 나타냅니다. ?
예를 들어, threadA 스레드에는 메인 스레드가 자금을 이체하는 중일 때 은행 이체 금액과 같은 특정 중요한 리소스를 보호하는 역할을 담당하는 모니터가 있습니다. ) 방식으로 인해 모니터가 해제되고 보호하는 리소스(이체 금액)가 일치하지 않을 가능성이 높습니다. 예를 들어 계정 A는 100만큼 감소하지만 계정 B는 100만큼 증가하지 않습니다
. 둘째, 중단 메커니즘
JAVA에서 중단 메커니즘을 올바르게 사용하는 방법에 대한 세부 정보가 너무 많습니다. Interrupted() 메서드와 isInterrupted() 메서드는 모두 현재 스레드가 중단된 상태인지 여부를 반영합니다. . ①interrupted()
소스 코드의 주석에서 볼 수 있듯이 현재 스레드의 중단 상태를 테스트하며 이 메서드는 중단 상태를 삭제합니다. ②isInterrupted( )/** * 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); }소스코드 주석에서 볼 수 있듯이 isInterrupted() 메소드는 인터럽트 상태를 삭제하지 않습니다. ③interrupted() 메소드와 차이점 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(boolean ClearInterrupted)를 호출하지만 한 매개변수는 true이고 다른 매개변수는 false이므로 첫 번째 차이점은 하나는 삭제된다는 것입니다.
소스 코드를 분석하면 두 번째 차이점은 return 문에 있음을 알 수 있습니다.
interrupted. ()는 현재 스레드의 중단 상태를 테스트하는 반면 isInterrupted()는 이 메서드를 호출하는 개체가 나타내는 스레드를 테스트합니다. 하나는 현재 스레드의 중단 상태를 테스트하는 인스턴스 메서드입니다. 인스턴스 개체로 표시되는 스레드의 인터럽트 상태를 테스트합니다./** * 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);
다음은 이 차이점을 더욱 명확히 하기 위해 구체적인 예를 사용합니다.
스레드 스레드의 스레드 클래스가 있습니다. CPU 실행을 얻을 수 있는 기회가 있습니다.
public static boolean interrupted() { return currentThread().isInterrupted(true); } /************************/ public boolean isInterrupted() { return isInterrupted(false); }메인 스레드가 1초 동안 휴면 상태가 된 후 7번째 줄에서 실행을 재개하고 스레드 스레드 중단을 요청합니다. 9행에서는 스레드가 중단된 상태인지 테스트합니다. 여기서 테스트하는 스레드는 무엇입니까? ? ? 대답은 메인 스레드입니다. 이유: (1) Interrupted()는 현재 스레드의 인터럽트 상태를 테스트합니다 (2) 메인 스레드는 명령문의 9번째 줄을 실행했으므로 메인 스레드는 현재 스레드입니다
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = ; i < ; i++) { System.out.println("i=" + (i + )); } } }
isInterrupted() 메서드의 예를 살펴보세요.
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线程没有被中断!!! //......
8번째 줄에서는 스레드 개체가 호출하는 isInterrupted() 메서드입니다. 따라서 테스트되는 것은 스레드 객체가 나타내는 스레드의 중단 상태입니다. 7행에서 메인 스레드가 스레드 스레드를 중단하도록 요청하므로 8행의 결과는 다음과 같습니다. true
JAVA 다중 스레드 중단 메커니즘 stop(), Interrupted(), isInterrupted()와 관련된 추가 기사 PHP 중국어 홈페이지를 주목해주세요!