java多線程七(Thread wait的用法)


    Thread類中把線程從running狀態轉化為非runnable狀態有一個方法就是wait方法。wait方法是線程的等待狀態。我們來看看wait方法簡單運用
    下面是一個wait方法的代碼
package ThreadTest;
/**
* thread wait方法詳解
* @author lingfengz
*
*/
public class WaitTest {
     public static void main(String[] args) {
          Waitthread wait = new Waitthread();
          Thread test1 = new Thread(wait,"線程1");
          Thread test2 = new Thread(wait,"線程2");
          Thread test3 = new Thread(wait,"線程3");
          Thread test4 = new Thread(wait,"線程4");
          Thread test5 = new Thread(wait,"線程5");
          
          test1.start();
          test2.start();
          test3.start();
          test4.start();
          test5.start();
     }
}
class Waitthread implements Runnable{
     private Object lock = new Object();
     /**
      * 實現run方法
      */
     @Override
     public void run() {
          // TODO Auto-generated method stub
          try{
              synchronized(lock){
                    System.out.println(Thread.currentThread().getName()+"開始了");
                   lock.wait();
              }
          }catch(InterruptedException e){
              e.getStackTrace();
          }
                    System.out.println(Thread.currentThread().getName()+"結束了");
     }
}
 

 

 
    從代碼運行的結果可以看出,wait是會釋放鎖的,但是線程下一步操作卻被掛起了。那么我們來看看通過notify();會不會喚醒線程
package ThreadTest;
/**
* thread wait方法詳解
* @author lingfengz
*
*/
public class WaitTest {
     public static void main(String[] args) {
       new Thread(new Wait1()).start();
       
       new Thread(new Wait2()).start();
     }
     
     public static class Wait1 implements Runnable{
      /**
       * 實現體育老師安排體育課代表進行點名
       */
          @Override
          public void run() {
              // TODO Auto-generated method stub
              //這個步驟我們可以想象成鎖住的是一節體育課
              synchronized (WaitTest.class) {
                   System.out.println("體育老師安排體育委員進行點名");
                   try {
                        //體育老師在樓下等待,並且交出體育課的鎖。等待體育課代表告訴他點名結束,他開始接管這節體育課
                        WaitTest.class.wait();
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch  block
                        e.printStackTrace();
                   }
                   System.out.println("體育老師得到點名的結果開始上課");
              }
          }
       
     }
     
     public static class Wait2 implements Runnable{
      
       /**
       * 實現體育課代表進行隊列點名
       */
          @Override
          public void run() {
              // TODO Auto-generated method stub
              synchronized (WaitTest.class) {
                   System.out.println("體育委員進行點名");
                   
                   try {
                        //點名需要花費的時間
                        Thread.sleep(1000L);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch  block
                        e.printStackTrace();
                   }
                   System.out.println("體育委員點名結束");
                   //通知體育老師點名結束了
                       WaitTest.class.notify();
                   
                   System.out.println("體育課代表帶人去操場");
              }
          }
       
       
     }
}
 
運行結果:
體育老師安排體育委員進行點名
體育委員進行點名
體育委員點名結束
體育課代表帶人去操場
體育老師得到點名的結果開始上課

 

我們從上面的代碼可以看到test1這個對象鎖.wait后。Waitthread線程中notify();進行了喚醒。線程被喚醒,如果我們把notify();給注銷掉會有什么樣的結果呢.
 
package ThreadTest;
/**
* thread wait方法詳解
* @author lingfengz
*
*/
public class WaitTest {
     public static void main(String[] args) {
       new Thread(new Wait1()).start();
       
       new Thread(new Wait2()).start();
     }
     
     public static class Wait1 implements Runnable{
      /**
       * 實現體育老師安排體育課代表進行點名
       */
          @Override
          public void run() {
              // TODO Auto-generated method stub
              //這個步驟我們可以想象成鎖住的是一節體育課
              synchronized (WaitTest.class) {
                   System.out.println("體育老師安排體育委員進行點名");
                   try {
                        //體育老師在樓下等待,並且交出體育課的鎖。等待體育課代表告訴他點名結束,他開始接管這節體育課
                        WaitTest.class.wait();
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch  block
                        e.printStackTrace();
                   }
                   System.out.println("體育老師得到點名的結果開始上課");
              }
          }
       
     }
     
     public static class Wait2 implements Runnable{
      
       /**
       * 實現體育課代表進行隊列點名
       */
          @Override
          public void run() {
              // TODO Auto-generated method stub
              synchronized (WaitTest.class) {
                   System.out.println("體育委員進行點名");
                   
                   try {
                        //點名需要花費的時間
                        Thread.sleep(1000L);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch  block
                        e.printStackTrace();
                   }
                   System.out.println("體育委員點名結束");
                   //通知體育老師點名結束了
                   //WaitTest.class.notify();
                   
                   System.out.println("體育課代表帶人去操場");
              }
          }
       
       
     }
}
 
 
運行結果
 
體育老師安排體育委員進行點名
體育委員進行點名
體育委員點名結束
體育課代表帶人去操場

 

從上面可以看到,體育委員沒有通知體育老師點名結束(notify();),那么體育老師還在等待體育委員的通知。但是體育委員已經帶人去操場了。這節體育課,如果體育委員不通知體育老師點名結束的,體育老師就不會來上課了。
從上面我們可以看到wait();方法是無限等待。那么我們生活中體育老師中,體育委員忘了通知體育老師,體育老師就不來上課了?答案肯定是體育老師還是會過來,但是肯定有一段等待的時間
那么我們試試給wait的其他方法。給wait一個時間的參數
 
package ThreadTest;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* thread wait方法詳解
* @author lingfengz
*
*/
public class WaitTest {
     public static void main(String[] args) {
       new Thread(new Wait1()).start();
       
       new Thread(new Wait2()).start();
     }
     
     public static class Wait1 implements Runnable{
      /**
       * 實現體育老師安排體育課代表進行點名
       */
          @Override
          public void run() {
              // TODO Auto-generated method stub
              //這個步驟我們可以想象成鎖住的是一節體育課
              synchronized (WaitTest.class) {
                   System.out.println("體育老師安排體育委員進行點名");
                   try {
                        //體育老師開始看手表,准備上課
                        System.out.println("體育老師開始等待時間:"+new  SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new  Date()));
                        //體育老師在樓下等待,並且交出體育課的鎖。等待體育課代表告訴他點名結束,他開始接管這節體育課。如果1000L之后體育課代表還不通知他,他將直接去操場上課
                        WaitTest.class.wait(1000L);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch  block
                        e.printStackTrace();
                   }
                   System.out.println("體育老師結束等待時間:"+new  SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new  Date()));
                   //System.out.println("體育老師得到點名的結果開始上課");
                   System.out.println("體育老師去操場開始上課");
              }
          }
       
     }
     
     public static class Wait2 implements Runnable{
      
       /**
       * 實現體育課代表進行隊列點名
       */
          @Override
          public void run() {
              // TODO Auto-generated method stub
              synchronized (WaitTest.class) {
                   System.out.println("體育委員進行點名");
                   
                   try {
                        //點名需要花費的時間
                        Thread.sleep(1000L);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch  block
                        e.printStackTrace();
                   }
                   System.out.println("體育委員點名結束");
                   //通知體育老師點名結束了
                   //WaitTest.class.notify();
                   
                   System.out.println("體育課代表帶人去操場");
              }
          }
     }
}
 
 
運行結果:
 
體育老師安排體育委員進行點名
體育老師開始等待時間:2019/03/18-13:01:08:995
體育委員進行點名
體育委員點名結束
體育課代表帶人去操場
體育老師結束等待時間:2019/03/18-13:01:09:999
體育老師去操場開始上課

 

 
從上面的執行結果來看wait,如果有時間參數的話,在時間參數之內被沒被喚醒的話,在時間到達之后他可以自己喚醒。
所以我們得出結論:wait的幾種情況
首先wait是會放棄鎖,進入等待區。第二wait可以被其他線程所喚醒。
第三如果wait有時間參數,就算沒有其他線程喚醒,他也會自動喚醒。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM