1. wait()
fait attendre le thread actuel jusqu'à ce qu'il soit réveillé, généralement en étant averti ou interrompu, ou jusqu'à ce qu'un certain temps en temps réel se soit écoulé.
Il appartient lui-même à une classe Object. Vous pouvez le voir dans le code source : public class Object {
En regardant le code source, vous pouvez voir qu'il existe trois méthodes surchargées. Le code source détaillé est le suivant :
//第一个重载函数
public final void wait() throws InterruptedException {
wait(0L);
}
//第二个重载函数
public final native void wait(long timeoutMillis) throws InterruptedException;
//第三个重载函数
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
if (timeoutMillis < 0) {
throw new IllegalArgumentException("timeoutMillis value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
timeoutMillis++;
}
wait(timeoutMillis);
}
Copier après la connexion
. Le code d'appel spécifique réel est le suivant :
Si la fonction d'attente est exécutée, dans ces 4 secondes, le verrou sera libéré et le fil sera suspendu. Si vous coopérez avec notify() dans ces quatre secondes, vous pouvez vous réveiller et obtenir le verrou. Si vous ne vous réveillez pas, attendez que les autres participent. Après 4 secondes, le verrou sera automatiquement libéré par défaut
Pendant que le thread actuel attend Thread.wait(), si le fil se termine, il peut automatiquement se réveiller et libérer automatiquement le verrou
@Override
public void run() {
synchronized (a) {
a.wait(4000);
}
}
Copier après la connexion
2.
join est une méthode de classe Thread
Voir son code source. Le code source spécifique est le suivant. La logique du paramètre temporel principal des trois méthodes surchargées
//第一个重载函数
public final synchronized void join(final long millis)
throws InterruptedException {
if (millis > 0) {
if (isAlive()) {
final long startTime = System.nanoTime();
long delay = millis;
do {
wait(delay);
} while (isAlive() && (delay = millis -
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);
}
} else if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
throw new IllegalArgumentException("timeout value is negative");
}
}
//第二个重载函数
/*等待该线程死亡的时间最多为毫秒加纳秒。 如果两个参数都为0,则意味着永远等待。
这个实现使用了This的循环。 等待电话以this.isAlive为条件。 当一个线程终止this。
调用notifyAll方法。 建议应用程序不要使用wait、notify或notifyAll on Thread实例。 */
public final synchronized void join(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0 && millis < Long.MAX_VALUE) {
millis++;
}
join(millis);
}
//第三个重载函数
/*等待线程死亡。
此方法的调用与调用的行为完全相同
InterruptedException—如果任何线程中断了当前线程。 当抛出此异常时,当前线程的中断状态将被清除。 */
public final void join() throws InterruptedException {
join(0);
}
Copier après la connexion
est la suivante :
- est inférieur à 0, une exception est. throwed
- est égal à 0, join(A ), déterminez si A existe et effectuez l'opération uniquement si elle existe. Ce thread exécute wait(0) et attend que le thread A termine son exécution avant de pouvoir se terminer
- est supérieur à 0, comme ci-dessus, sauf qu'il exécute wait(long millis), et l'opération ne peut être poursuivie que une fois le temps d'attente terminé
3. sleep()
Comparez avec la fonction d'attente précédente
- sleep(long mills) : abandonne les ressources CPU, mais ne libère pas les ressources de verrouillage.
- wait() : abandonnez les ressources CPU et verrouillez les ressources.
Affichez le code source de la fonction sleep, il y a deux fonctions surchargées
Les deux sont des fonctions de la classe Thread
/*根据系统计时器和调度器的精度和准确性,
使当前执行的线程在指定的毫秒数内处于睡眠状态(暂时停止执行)。
线程不会失去任何监视器的所有权。*/
public static native void sleep(long millis) throws InterruptedException;
/*导致当前执行的线程在指定的毫秒数加上指定的纳秒数
(取决于系统计时器和调度器的精度和准确性)内休眠(暂时停止执行)。
线程不会失去任何监视器的所有权。 */
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0 && millis < Long.MAX_VALUE) {
millis++;
}
sleep(millis);
}
Copier après la connexion
4.Affichez le code source de la fonction rendement(), une surchargée. function
both C'est une fonction de la classe Thread qui indique au planificateur que le thread actuel est prêt à abandonner son utilisation actuelle du processeur. Le planificateur peut ignorer cette invite.
Yield est une tentative heuristique visant à améliorer la progression relative entre les threads qui, autrement, surutiliseraient le processeur. Son utilisation doit être associée à une analyse détaillée et à une analyse comparative pour garantir qu’elle produit réellement l’effet escompté.
Utiliser cette méthode est rarement appropriée. Il peut être utilisé à des fins de débogage ou de test, où il peut aider à reproduire des erreurs dues à des conditions de concurrence. Cela peut également être utile lors de la conception de constructions de contrôle de concurrence telles que celles du package java.util.concurrent.locks.
public static native void yield();
Copier après la connexion
En général, les principales fonctions de la fonction rendement sont :
Abandonner la planification du processeur et mettre les threads en pause, mais l'heure ne peut pas être spécifiée par l'utilisateur
Elle ne peut permettre qu'à la même priorité d'avoir des opportunités d'exécution
5 .Résumé
attendez Mettez le fil en pause, abandonnez le processeur et relâchez le verrou. (Classe d'objet)
join met le thread en pause, et ce n'est qu'après avoir exécuté le thread qu'il peut revenir à son propre thread. (Classe Thread)
sleep met le thread en pause et abandonne le processeur sans relâcher le verrou. (Classe Thread)
yield met le thread en pause, mais il ne peut pas être spécifié par l'utilisateur. Il ne peut que donner la même priorité à la possibilité de s'exécuter. (Classe Thread)
5.1 La différence entre wait et join
Après avoir lu le code source et le code logique ci-dessus, parlons des similitudes et des différences entre les deux
En général
fonction wait : met le thread actuel dans un état d'attente, wait() sera utilisé avec les méthodes notify() et notifyAll(). notify est la fonction de réveil
- fonction de jointure : attendez la fin de ce fil avant d'exécuter votre propre fil. Sa fonction principale est de synchroniser, en changeant l'exécution entre les threads de "parallèle" à "série". Lorsque la méthode join() du thread B est appelée dans le thread A, le processus d'exécution du thread
- change : le thread A doit attendre que le thread B termine son exécution avant de pouvoir continuer l'exécution Points communs :
pause Le fil de discussion actuel
- peut être réveillé par une interruption
- La différence est :
La différence
attendre
join |
| classe | Classe d'objet
Cours de fil | | Objectif | Communication inter-thread
Tri, laissez-le passer en série |
| Synchronisation | Doit être synchronisé
Vous ne pouvez pas utiliser synchronisé |
|
5.2 La différence entre attendre et dormir |
attends( ) : abandonnez les ressources CPU et verrouillez les ressources.
sleep(long mills) : abandonne les ressources CPU, mais ne libère pas les ressources de verrouillage.
La différence dépend principalement du mécanisme de fonctionnement du CPU :
La différence considère principalement deux points : 1. Si le CPU continue de s'exécuter, 2. Si le verrou est libéré.
En dernière analyse :
wait, notify, notifyall sont toutes des méthodes de l'objet Object. Elles sont utilisées ensemble et sont utilisées pour le mécanisme de verrouillage, donc le verrou sera libéré
Et sleep est une classe Thread, qui n'a rien à voir avec le verrou et ne libérera pas le verrou
Mais les deux abandonneront les ressources CPU
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!