Maison  >  Article  >  Java  >  Explication détaillée des méthodes thread rendement() et thread sleep sleep() en Java

Explication détaillée des méthodes thread rendement() et thread sleep sleep() en Java

高洛峰
高洛峰original
2017-01-05 15:42:581984parcourir

Rendement du fil : rendement()
rendement() rendement. Il permet au thread actuel d'entrer dans « l'état prêt » à partir de « l'état d'exécution », permettant ainsi à d'autres threads en attente avec la même priorité d'obtenir les droits d'exécution. Cependant, il n'y a aucune garantie qu'après que le thread actuel ait appelé rendement(), autre ; les threads en attente auront la même priorité. Le thread pourra certainement obtenir les droits d'exécution ; il est également possible que le thread actuel soit entré dans « l'état d'exécution » et continue de s'exécuter !
Exemple :

class ThreadA extends Thread{
  public ThreadA(String name){ 
    super(name); 
  } 
  public synchronized void run(){ 
    for(int i=0; i <10; i++){ 
      System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i); 
      // i整除4时,调用yield
      if (i%4 == 0)
        Thread.yield();
    } 
  } 
} 
 
public class YieldTest{ 
  public static void main(String[] args){ 
    ThreadA t1 = new ThreadA("t1"); 
    ThreadA t2 = new ThreadA("t2"); 
    t1.start(); 
    t2.start();
  } 
}

(Un certain temps) résultat d'exécution :

t1 [5]:0
t2 [5]:0
t1 [5]:1
t1 [5]:2
t1 [5]:3
t1 [5]:4
t1 [5]:5
t1 [5]:6
t1 [5]:7
t1 [5]:8
t1 [5]:9
t2 [5]:1
t2 [5]:2
t2 [5]:3
t2 [5]:4
t2 [5]:5
t2 [5]:6
t2 [5]:7
t2 [5]:8
t2 [5]:9

Explication du résultat :
Quand "thread t1" peut être un entier de 4 , et il n'y a pas de commutateur vers "thread t2". Cela montre que bien que rendement() puisse permettre à un thread d'entrer dans « l'état prêt » à partir de « l'état d'exécution », cela ne permet pas nécessairement à d'autres threads d'obtenir les droits d'exécution du processeur (c'est-à-dire que d'autres threads entrent dans « l'état d'exécution ») ; "), même si ces "Autres threads" ont la même priorité que le thread appelant actuellement rendement().

Comparaison de rendement() et wait() :
Nous savons que la fonction de wait() est de faire entrer le thread actuel dans "l'état d'attente (bloqué)" à partir de "l'état d'exécution" et relâchez-le également. La fonction de rendement() est de céder, cela fera également que le thread actuel quittera "l'état d'exécution". La différence entre eux est la suivante :
(1) wait() permet au thread d'entrer dans "l'état d'attente (blocage)" à partir de "l'état d'exécution", tandis que rendement() permet au thread d'entrer dans "l'état prêt" à partir de l'"état d'exécution"".
(2) wait() amènera le thread à libérer le verrou de synchronisation de l'objet qu'il détient, mais la méthode rendement() ne libérera pas le verrou.
L'exemple suivant montre que rendement() ne libérera pas le verrou :

public class YieldLockTest{ 
 
  private static Object obj = new Object();
 
  public static void main(String[] args){ 
    ThreadA t1 = new ThreadA("t1"); 
    ThreadA t2 = new ThreadA("t2"); 
    t1.start(); 
    t2.start();
  } 
 
  static class ThreadA extends Thread{
    public ThreadA(String name){ 
      super(name); 
    } 
    public void run(){ 
      // 获取obj对象的同步锁
      synchronized (obj) {
        for(int i=0; i <10; i++){ 
          System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i); 
          // i整除4时,调用yield
          if (i%4 == 0)
            Thread.yield();
        }
      }
    } 
  } 
}

(un certain temps) Résultats d'exécution :

t1 [5]:0
t1 [5]:1
t1 [5]:2
t1 [5]:3
t1 [5]:4
t1 [5]:5
t1 [5]:6
t1 [5]:7
t1 [5]:8
t1 [5]:9
t2 [5]:0
t2 [5]:1
t2 [5]:2
t2 [5]:3
t2 [5]:4
t2 [5]:5
t2 [5]:6
t2 [5]:7
t2 [5]:8
t2 [5]:9

Description du résultat :
Principal thread Deux threads t1 et t2 sont démarrés dans main. t1 et t2 feront référence au verrou de synchronisation du même objet dans run(), c'est-à-dire synchronisé(obj). Pendant l'exécution de t1, bien qu'il appelle Thread.yield(); cependant, t2 n'obtiendra pas le droit d'exécution du CPU. Parce que t1 n'a pas libéré le "verrou de synchronisation détenu par obj" !

Thread sleep : sleep()
sleep() est défini dans Thread.java.
La fonction de sleep() est de mettre le thread actuel en veille, c'est-à-dire que le thread actuel entrera dans « l'état de veille (bloqué) » à partir de « l'état d'exécution ». sleep() spécifiera le temps de sommeil, et le temps de sommeil du thread sera supérieur/égal au temps de sommeil ; lorsque le thread sera à nouveau réveillé, il passera de « l'état bloqué » à « l'état prêt », attendant ainsi le Exécution de la planification du processeur.
Exemple :

class ThreadA extends Thread{
  public ThreadA(String name){ 
    super(name); 
  } 
  public synchronized void run() { 
    try {
      for(int i=0; i <10; i++){ 
        System.out.printf("%s: %d\n", this.getName(), i); 
        // i能被4整除时,休眠100毫秒
        if (i%4 == 0)
          Thread.sleep(100);
      } 
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  } 
} 
 
public class SleepTest{ 
  public static void main(String[] args){ 
    ThreadA t1 = new ThreadA("t1"); 
    t1.start(); 
  } 
}

Résultat d'exécution :

t1: 0
t1: 1
t1: 2
t1: 3
t1: 4
t1: 5
t1: 6
t1: 7
t1: 8
t1: 9

Description du résultat :
Le programme est relativement simple, démarrant le thread t1 dans le thread principal main. Après le démarrage de t1, lorsque le calcul i dans t1 est divisible par 4, t1 dormira pendant 100 millisecondes via Thread.sleep(100).

Comparaison entre sleep() et wait() :
Nous savons que la fonction de wait() est de faire passer le thread actuel à "l'état d'attente (bloqué)" à partir de "l'état d'exécution" et relâchez-le également. La fonction de sleep() est également de faire passer le thread actuel à « l’état de veille (bloqué) » à partir de « l’état d’exécution ».
Cependant, wait() libérera le verrou de synchronisation de l'objet, mais sleep() ne libérera pas le verrou.
L'exemple suivant démontre que sleep() ne libérera pas le verrou.

public class SleepLockTest{ 
 
  private static Object obj = new Object();
 
  public static void main(String[] args){ 
    ThreadA t1 = new ThreadA("t1"); 
    ThreadA t2 = new ThreadA("t2"); 
    t1.start(); 
    t2.start();
  } 
 
  static class ThreadA extends Thread{
    public ThreadA(String name){ 
      super(name); 
    } 
    public void run(){ 
      // 获取obj对象的同步锁
      synchronized (obj) {
        try {
          for(int i=0; i <10; i++){ 
            System.out.printf("%s: %d\n", this.getName(), i); 
            // i能被4整除时,休眠100毫秒
            if (i%4 == 0)
              Thread.sleep(100);
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    } 
  } 
}

Résultats d'exécution :

t1: 0
t1: 1
t1: 2
t1: 3
t1: 4
t1: 5
t1: 6
t1: 7
t1: 8
t1: 9
t2: 0
t2: 1
t2: 2
t2: 3
t2: 4
t2: 5
t2: 6
t2: 7
t2: 8
t2: 9

Description du résultat :
Deux threads t1 et t2 sont démarrés dans le thread principal main. t1 et t2 feront référence au verrou de synchronisation du même objet dans run(), c'est-à-dire synchronisé(obj). Pendant l'exécution de t1, bien qu'il appelle Thread.sleep(100); cependant, t2 n'obtiendra pas le droit d'exécution du processeur. Parce que t1 n'a pas libéré le "verrou de synchronisation détenu par obj" !
Notez que si nous commentons synchronisé (obj) et exécutons à nouveau le programme, t1 et t2 peuvent basculer l'un vers l'autre. Voici le code source après avoir commenté synchronisé(obj) :

public class SleepLockTest{ 
 
  private static Object obj = new Object();
 
  public static void main(String[] args){ 
    ThreadA t1 = new ThreadA("t1"); 
    ThreadA t2 = new ThreadA("t2"); 
    t1.start(); 
    t2.start();
  } 
 
  static class ThreadA extends Thread{
    public ThreadA(String name){ 
      super(name); 
    } 
    public void run(){ 
      // 获取obj对象的同步锁
//      synchronized (obj) {
        try {
          for(int i=0; i <10; i++){ 
            System.out.printf("%s: %d\n", this.getName(), i); 
            // i能被4整除时,休眠100毫秒
            if (i%4 == 0)
              Thread.sleep(100);
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
//      }
    } 
  } 
}


Articles plus détaillés liés aux méthodes thread rendement() et thread sleep() en Java Veuillez payer attention au site 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