溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JAVA線程sleep()和wait()詳解及實(shí)例

發(fā)布時(shí)間:2020-08-26 16:23:55 來源:腳本之家 閱讀:287 作者:lqh 欄目:編程語言

JAVA線程sleep()和wait()詳解及實(shí)例

sleep

1.sleep是Thread的一個(gè)靜態(tài)(static)方法。使得Runnable實(shí)現(xiàn)的線程也可以使用sleep方法。而且避免了線程之前相互調(diào)用sleep()方法,引發(fā)死鎖。

2.sleep()執(zhí)行時(shí)需要賦予一個(gè)沉睡時(shí)間。在沉睡期間(阻塞線程期間),CPU會(huì)放棄這個(gè)線程,執(zhí)行其他任務(wù)。當(dāng)沉睡時(shí)間到了之后,該線程會(huì)自動(dòng)蘇醒,不過此時(shí)線程不會(huì)立刻被執(zhí)行,而是要等CPU分配資源,和其他線程進(jìn)行競(jìng)爭(zhēng)。

3.此外如果這個(gè)線程之前獲取了一個(gè)機(jī)鎖,在沉睡期間,這個(gè)機(jī)鎖不會(huì)釋放。其他等待這個(gè)機(jī)鎖的程序,必須等待這個(gè)線程醒來,且執(zhí)行完后才能運(yùn)行。

sleep相關(guān)代碼

public class ThreadTest2 {

  public static void main(String[] args){
    System.out.println("begin our test");
    ThreadSleep sleep = new ThreadSleep();
    try {
      Thread thread1 = new Thread(sleep,"路人甲");
      Thread thread2 = new Thread(sleep,"路人乙");
      thread1.start();
      thread2.start();
    }catch(Exception e){
      e.printStackTrace();
    }
    System.out.println("test is over");
  }


}

 class ThreadSleep implements Runnable{

   int count = 0;

   @Override
   public void run(){
     System.out.println(Thread.currentThread().getName() + " say : hello sleep !!");
     count();

   }

   public void count(){
     while(count < 20) {
         System.out.println(Thread.currentThread().getName() + " say : count is " + count);
         try {
           count++;
           Thread.sleep(100);
         } catch (Exception e) {
           e.printStackTrace();
         }
     }

   }
}

輸出日志

begin our test
test is over
路人甲 say : hello sleep !!
路人甲 say : count is 0
路人乙 say : hello sleep !!
路人乙 say : count is 1
路人甲 say : count is 2
路人乙 say : count is 2
路人甲 say : count is 4
路人乙 say : count is 4
路人甲 say : count is 6
路人乙 say : count is 7
路人乙 say : count is 8
路人甲 say : count is 8
路人甲 say : count is 10
路人乙 say : count is 10
路人乙 say : count is 12
路人甲 say : count is 12
路人乙 say : count is 14
路人甲 say : count is 14
路人甲 say : count is 16
路人乙 say : count is 16
路人甲 say : count is 18
路人乙 say : count is 18

通過日志可以發(fā)現(xiàn)線程甲和線程乙基本是交替執(zhí)行,但是并不規(guī)律,且出現(xiàn)了并發(fā)問題。

該情況是由于代碼中設(shè)置了睡眠時(shí)間為100毫秒,由于count遞增執(zhí)行速度很快,所以線程差不多是同時(shí)睡眠,然后同時(shí)蘇醒并導(dǎo)致了并發(fā)的出現(xiàn)。

接下來要添加synchronize塊,檢查sleep時(shí)機(jī)鎖是否釋放

public class ThreadTest2 {

  public static void main(String[] args){
    System.out.println("begin our test");
    ThreadSleep sleep = new ThreadSleep();
    try {
      Thread thread1 = new Thread(sleep,"路人甲");
      Thread thread2 = new Thread(sleep,"路人乙");
      thread1.start();
      thread2.start();
    }catch(Exception e){
      e.printStackTrace();
    }
    System.out.println("test is over");
  }


}

class ThreadSleep implements Runnable{

  int count = 0;

  @Override
  public void run(){
    System.out.println(Thread.currentThread().getName() + " say : hello sleep !!");
    count();

  }

  public void count(){
    while(count < 20) {
      synchronized (this) {
        System.out.println(Thread.currentThread().getName() + " say : count is " + count);
        try {
          count++;
          Thread.sleep(100);
        } catch (Exception e) {
          e.printStackTrace();
        }

      }
    }

  }
}

輸出日志

begin our test
路人甲 say : hello sleep !!
路人甲 say : count is 0
test is over
路人乙 say : hello sleep !!
路人甲 say : count is 1
路人甲 say : count is 2
路人甲 say : count is 3
路人甲 say : count is 4
路人甲 say : count is 5
路人甲 say : count is 6
路人甲 say : count is 7
路人甲 say : count is 8
路人甲 say : count is 9
路人甲 say : count is 10
路人甲 say : count is 11
路人甲 say : count is 12
路人甲 say : count is 13
路人甲 say : count is 14
路人甲 say : count is 15
路人甲 say : count is 16
路人甲 say : count is 17
路人甲 say : count is 18
路人甲 say : count is 19
路人乙 say : count is 20

通過日志可以看出,基本是線程甲在執(zhí)行,這是因?yàn)閟leep時(shí),機(jī)鎖一直在線程甲上,所以線程乙只能一直等待直到線程甲釋放鎖。

wait

1.wait()是Object類的一個(gè)方法。當(dāng)調(diào)用wait()方法時(shí),該線程會(huì)進(jìn)入和該對(duì)象相關(guān)的等待池中,并釋放它所擁有的機(jī)鎖。

2.執(zhí)行wait()后,必須使用notify()方法或notifyAll()方法或設(shè)置等待時(shí)間(wait(long time))喚醒在等待線程池中的線程。

3.wait()必須放在synchronized block中,否則會(huì)在運(yùn)行時(shí)報(bào)“java.lang.IllegalMonitorStateException”異常

wait相關(guān)代碼

public class ThreadTest2 {

  public static void main(String[] args) {
    System.out.println("begin our test");
    ThreadSleep sleep = new ThreadSleep();
    try {
      Thread thread1 = new Thread(sleep, "路人甲");
      Thread thread2 = new Thread(sleep, "路人乙");
      thread1.start();
      thread2.start();
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("test is over");
  }
}

class ThreadSleep implements Runnable {

  int count = 0;

  @Override
  public void run() {
    System.out.println(Thread.currentThread().getName() + " say : hello sleep !!");
    count();

  }

  public void count() {
    while (count < 20) {
      synchronized (this) {
        System.out.println(Thread.currentThread().getName() + " say : count is " + count);
        try {
          count++;
          this.wait(100);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }

  }
}

輸出日志

begin our test
路人甲 say : hello sleep !!
路人甲 say : count is 0
test is over
路人乙 say : hello sleep !!
路人乙 say : count is 1
路人甲 say : count is 2
路人乙 say : count is 3
路人甲 say : count is 4
路人乙 say : count is 5
路人甲 say : count is 6
路人乙 say : count is 7
路人甲 say : count is 8
路人乙 say : count is 9
路人甲 say : count is 10
路人乙 say : count is 11
路人甲 say : count is 12
路人乙 say : count is 13
路人乙 say : count is 14
路人甲 say : count is 15
路人乙 say : count is 16
路人甲 say : count is 17
路人乙 say : count is 18
路人甲 say : count is 19

通過日志可以發(fā)現(xiàn)在wait的情況下,機(jī)鎖會(huì)被釋放。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI