Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Methoden thread yield() und thread sleep sleep() in Java

Detaillierte Erläuterung der Methoden thread yield() und thread sleep sleep() in Java

高洛峰
高洛峰Original
2017-01-05 15:42:581920Durchsuche

Thread yield: yield()
yield() yields. Dadurch kann der aktuelle Thread aus dem „Laufzustand“ in den „Bereitschaftszustand“ wechseln, wodurch andere wartende Threads mit derselben Priorität Ausführungsrechte erhalten. Es gibt jedoch keine Garantie dafür, dass nach dem Aufruf von yield() durch den aktuellen Thread „other“ aufgerufen wird Wartende Threads haben auf jeden Fall die gleiche Priorität. Es ist auch möglich, dass der aktuelle Thread in den „Laufzustand“ übergegangen ist und weiterläuft.
Beispiel:

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();
  } 
}

(Eine bestimmte Zeit) laufendes Ergebnis:

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

Erklärung des Ergebnisses:
Wenn „Thread t1“ eine ganze Zahl von 4 sein kann , und Es gibt keinen Wechsel zu „Thread t2“. Dies zeigt, dass yield() es einem Thread zwar ermöglichen kann, aus dem „Laufzustand“ in den „Bereitschaftszustand“ zu wechseln, andere Threads jedoch nicht unbedingt CPU-Ausführungsrechte erhalten können (d. h. andere Threads gelangen in den „Laufzustand“) "), auch wenn diese „Anderen Threads“ die gleiche Priorität haben wie der Thread, der gerade yield() aufruft.

Vergleich von yield() und wait():
Wir wissen, dass die Funktion von wait() darin besteht, den aktuellen Thread vom „Laufzustand“ in den „Wartezustand (blockiert)“ zu versetzen Geben Sie auch die Synchronisierungssperre frei. Die Funktion von yield () besteht darin, nachzugeben und den aktuellen Thread auch dazu zu bringen, den „Laufstatus“ zu verlassen. Der Unterschied zwischen ihnen ist:
(1) wait() ermöglicht es dem Thread, vom „Laufzustand“ in den „Wartezustand (Blockierungszustand)“ zu wechseln, während yield() es dem Thread ermöglicht, von dort in den „Bereitschaftszustand“ einzutreten der „Laufzustand“.
(2) wait() bewirkt, dass der Thread die Synchronisationssperre des von ihm gehaltenen Objekts aufhebt, die Methode yield() gibt die Sperre jedoch nicht auf.
Das folgende Beispiel zeigt, dass yield() die Sperre nicht aufhebt:

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();
        }
      }
    } 
  } 
}

(eine bestimmte Zeit) Ergebnisse ausführen:

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

Ergebnisbeschreibung:
Main Thread Zwei Threads t1 und t2 werden in main gestartet. t1 und t2 verweisen in run () auf die Synchronisationssperre desselben Objekts, dh synchronisiert (obj). Während der Ausführung von t1 wird zwar Thread.yield(); aufgerufen, jedoch erhält t2 nicht das CPU-Ausführungsrecht. Denn t1 hat die „von obj gehaltene Synchronisationssperre“ nicht freigegeben!

Thread-Sleep: sleep()
sleep() ist in Thread.java definiert.
Die Funktion von Sleep () besteht darin, den aktuellen Thread in den Ruhezustand zu versetzen, dh der aktuelle Thread wechselt vom „Laufzustand“ in den „Ruhezustand (blockiert)“. Sleep () gibt die Ruhezeit an, und die Ruhezeit des Threads ist größer/gleich der Ruhezeit. Wenn der Thread wieder aufgeweckt wird, wechselt er vom „blockierten Zustand“ in den „Bereitschaftszustand“ und wartet auf die Ruhezeit Planungsausführung der CPU.
Beispiel:

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(); 
  } 
}

Laufergebnis:

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

Erklärung des Ergebnisses:
Das Programm ist relativ einfach, es startet Thread t1 im Hauptthread main. Nachdem t1 gestartet wurde und die Berechnung i in t1 durch 4 teilbar ist, schläft t1 über Thread.sleep(100) 100 Millisekunden lang.

Vergleich zwischen Sleep() und Wait():
Wir wissen, dass die Funktion von Wait() darin besteht, den aktuellen Thread vom „Laufzustand“ in den „Wartezustand (blockiert)“ zu versetzen Geben Sie auch die Synchronisierungssperre frei. Die Funktion von Sleep () besteht darin, den aktuellen Thread auch aus dem „Laufzustand“ in den „Ruhezustand (blockiert)“ zu versetzen.
Wait() gibt jedoch die Synchronisationssperre des Objekts frei, aber sleep() gibt die Sperre nicht frei.
Das folgende Beispiel zeigt, dass sleep() die Sperre nicht aufhebt.

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();
        }
      }
    } 
  } 
}

Laufergebnisse:

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

Ergebnisbeschreibung:
Zwei Threads t1 und t2 werden im Hauptthread main gestartet. t1 und t2 verweisen in run () auf die Synchronisationssperre desselben Objekts, dh synchronisiert (obj). Während der Ausführung von t1 wird zwar Thread.sleep(100) aufgerufen, t2 erhält jedoch nicht das CPU-Ausführungsrecht. Denn t1 hat die „von obj gehaltene Synchronisationssperre“ nicht freigegeben!
Beachten Sie, dass t1 und t2 zueinander wechseln können, wenn wir synchronisiert (obj) auskommentieren und das Programm erneut ausführen. Das Folgende ist der Quellcode nach dem Kommentieren von synchronisiert (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();
        }
//      }
    } 
  } 
}


Ausführlichere Artikel zu den Methoden thread yield () und thread sleep () in Java Bitte zahlen Sie Achtung PHP chinesische Website!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn