Maison  >  Article  >  Java  >  Mécanisme d'interruption multithread JAVA stop(), interrompu(), isInterrupted()

Mécanisme d'interruption multithread JAVA stop(), interrompu(), isInterrupted()

高洛峰
高洛峰original
2017-01-05 16:35:421491parcourir

1. Introduction

Cet article enregistre quelques points de connaissances sur le mécanisme d'interruption dans le multi-threading JAVA. Principalement les différences entre la méthode stop, les méthodes interrompues() et isInterrupted(), et une simple analyse de l'implémentation du code source.

Il existe 3 façons de terminer un thread en cours d'exécution en JAVA

①Le thread se termine normalement, c'est-à-dire que la méthode run() a été exécutée

②Utilisez stop dans le Thread La méthode class () termine de force le thread. Cependant, la méthode stop() a expiré et n'est pas recommandée.

③ Utilisez le mécanisme d'interruption

Il n'y a rien de mal à ce que le thread se termine normalement. Le mécanisme d'interruption est présenté en détail ci-dessous. Regardons d'abord la méthode stop(). Le code source, la clé réside dans les commentaires sur le code source. Cela explique pourquoi stop() n'est pas sécurisé. Quel thread la méthode stop() arrête-t-elle ?

/**
* 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&#39;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());
}

Le commentaire ci-dessus, les lignes 9 à 16 indiquent que la méthode stop() peut arrêter "d'autres threads". Le thread qui exécute l'instruction de la méthode thread.stop() est appelé le thread actuel, et les « autres threads » sont les threads représentés par le thread objet qui appelle la méthode thread.stop().

Par exemple :

public static void main(String[] args) {
MyThread thread = new MyThread...
//.....
thread.stop();
//....
}

Dans la méthode main, le thread actuel est le thread principal. Il s'exécute à la ligne 4 et veut arrêter "l'autre thread "thread". Cet autre thread est le thread représenté par l'objet thread de la nouvelle classe MyThread.

Les lignes 21 à 23 indiquent que l'on peut être arrêté Un fil qui n'a pas encore été démarré. Son effet est le suivant : lorsque le fil est démarré, il se termine immédiatement. Les commentaires après la ligne 48 de

indiquent profondément pourquoi la méthode stop() est obsolète ! ?

Par exemple, le thread threadA dispose de moniteurs, qui sont chargés de protéger certaines ressources critiques, comme le montant d'un virement bancaire, lorsque le thread principal est en train de transférer de l'argent. ) En conséquence, le moniteur est libéré et les ressources qu'il protège (montant du transfert) sont susceptibles d'être incohérentes. Par exemple, le compte A diminue de 100, mais le compte B n'augmente pas de 100

. deuxièmement, le mécanisme d'interruption

Il y a trop de détails sur la façon d'utiliser correctement le mécanisme d'interruption en JAVA. La méthode interrompu() et la méthode isInterrupted() indiquent toutes deux si le thread actuel est dans un état interrompu. . ①interrupted()

Comme le montrent les commentaires dans le code source, il teste l'état d'interruption du thread actuel, et cette méthode effacera l'état d'interruption
/**
* 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()

Comme le montrent les commentaires du code source, la méthode isInterrupted() n'efface pas l'état de l'interruption
/**
* 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);
}

③La différence entre la méthode interrompue() et la méthode interrompue(). Méthode isInterrupted()

Comme le montre le code source, les deux méthodes appellent isInterrupted(boolean ClearInterrupted), mais un paramètre est vrai et l'autre paramètre est faux. Par conséquent, la première différence est que l'une sera effacée. le bit d'indicateur d'interruption, et l'autre n'effacera pas le bit d'indicateur d'interruption

En analysant le code source, vous pouvez voir que la deuxième différence réside dans l'instruction return :

/**
* 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);

interrupted. () teste l'état d'interruption du thread actuel, tandis que isInterrupted() teste le thread représenté par l'objet qui appelle cette méthode. One est une méthode statique (elle teste l'état d'interruption du thread actuel. One est la méthode d'instance (). qui teste l'état d'interruption du thread représenté par l'objet instance).

Ce qui suit utilise un exemple spécifique pour clarifier davantage cette différence

public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
/************************/
public boolean isInterrupted() {
return isInterrupted(false);
}
Il existe une personnalisation de la classe thread. a la possibilité d’obtenir l’exécution du CPU.

Après que le thread principal se soit endormi pendant 1 seconde, il reprend l'exécution à la ligne 7 et demande d'interrompre le thread.

La ligne 9 teste si le thread est dans un état interrompu. Quel thread est testé ici ? ? ? La réponse est le fil conducteur. Parce que :

(1) interrompu() teste l'état d'interruption du thread actuel
public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = ; i < ; i++) {
System.out.println("i=" + (i + ));
}
}
}

(2) Le thread principal a exécuté la 9ème ligne d'instructions, donc le thread principal est le thread actuel

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线程没有被中断!!!
      //......
Regardez l'exemple de la méthode isInterrupted() :

A la ligne 8, c'est la méthode isInterrupted() appelée par l'objet thread. Par conséquent, ce qui est testé est l’état d’interruption du thread représenté par l’objet thread. Puisqu'à la ligne 7, le thread principal demande d'interrompre le thread du thread, le résultat à la ligne 8 est : true

Plus d'articles liés au mécanisme d'interruption multithread JAVA stop(), interrompu(), isInterrupted() Veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn