天天看點

java多線程 sleep 與 wait

在多線程中使線程阻塞有那麼幾種情況:

  1. sleep()的調用
  2. wait()的調用
  3. 遇到阻塞io
  4. suspend使線程暫停執行(這個方法已棄用)
  5. 在未持有鎖時,進入同一個對象鎖的同步代碼塊時,等待鎖的時候。

那麼我們這篇文章就看一看sleep()和wait()分别都能幹什麼。

sleep()

Thread.sleep(long millis),可以使目前線程休眠指定的毫秒數。但是需要注意的是,調用該方法并不會釋放鎖,我們通過代碼來看:

class T extends Thread{
    @Override
    synchronized public void run() {
        for(int i = ; i < ; i++){
            System.out.println(Thread.currentThread().getName() + ": " + i);
            if(i == ){
                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
public class Test {
    public static void main(String[] args){
        T t = new T();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.setName("線程1");
        t2.setName("線程2");
        t1.start();
        t2.start();
    }
}
           

結果:

線程: 
線程: 
線程: 
線程: 
線程: 
線程:  // 這裡雖然線程暫停了執行,但是線程2并沒有搶到執行權
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
           

運作得知,該代碼中雖然在i==5的時候,使線程sleep了,但是,線程并沒有釋放鎖,是以該代碼還是同步執行的。

wait()

這個方法可以帶上參數或者不帶參數,不帶參數的時候需要手動顯示的去notify(),才可以将該線程喚醒,在這之前線程是一直阻塞的,而帶參數的話是在一段時間内,如果都沒有将該線程喚醒,則會自動喚醒該線程,這裡我們使用帶參數的wait方法:

class T extends Thread{
    @Override
    synchronized public void run() {
        for(int i = ; i < ; i++){
            System.out.println(Thread.currentThread().getName() + ": " + i);
            if(i == ){
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
public class Test {
    public static void main(String[] args){
        T t = new T();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.setName("線程1");
        t2.setName("線程2");
        t1.start();
        t2.start();
    }
}
           

結果:

線程: 
線程: 
線程: 
線程: 
線程: 
線程:  // 這裡可以看出,線程立馬釋放了鎖,讓線程2搶到了執行權
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: 
線程: