java-線程-基礎

來源:互聯網
上載者:User

標籤:區別   喚醒   sys   通過   sleep   reads   inter   oid   info   

線程狀態及轉化

借用網上的一幅圖:

說明:
線程一共分為5種狀態

建立狀態(new)

線程對象被建立後,就進入了建立狀態,例如:Thread t = new Thread();

就緒狀態(Runnable)

線程對象被建立後,其它線程調用了該對象的start()方法,從而來啟動該線程。
例如,thread.start()。處於就緒狀態的線程,然後等待CPU調度執行。可不是run()方法-_-;

當如果多次調用start(),這時會報異常。

 public synchronized void start() {        //A zero status value corresponds to state "NEW".        if (threadStatus != 0)            throw new IllegalThreadStateException();

運行(Running)

線程擷取CPU許可權進行執行。需要注意的是,線程只能從就緒狀態進入到運行狀態。

堵塞(blocked)

阻塞狀態是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分三種,狀態是兩種(blocked 和waiting):

  • 等待阻塞 -- 通過調用線程的wait()方法,讓線程等待某工作的完成。
  • 同步阻塞 -- 線程在擷取synchronized同步鎖失敗(因為鎖被其它線程所佔用),它會進入同步阻塞狀態。
  • 其他阻塞 -- 通過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀態。當sleep()狀態逾時、join()等待線程終止或者逾時、或者I/O處理完畢時,線程重新轉入就緒狀態。

blocked 和waiting 區別,blocked是在臨界點外面等待進入,waiting是在臨界點裡面等待notify,當線程調用了join方法,jion了另外的線程的時候,也會進入waiting狀態,等待被它jion的線程結束。

死亡(Dead)

線程執行完了或者因異常退出了run()方法,該線程結束生命週期。

線程的建立

線程建立有3中方式:

1、繼承Thrad:

Thread t = new Thread(){    public vvoid run(){        System.out.println("new Thread");      };};

2、實現Runnable介面:

Thread t = new Thread(new Runnable(){    public void run(){        System.out.println("new Thread");      };});

3、使用Callable和Future建立線程

FutureTask<String> ft = new futureTask<String>(){    public String call() throws Exception{        System.out.println("new Thread");          return "abc";    }}Thread t = new Thread(ft);ft.start();String result= ft.get();
線程方法Object中方法

wait(),notify(),notifyAll()都是定義在Object類中,它們都是依賴於同步鎖,而同步鎖是對象鎖持有,並且每個對象只有一個!這就是為什麼notify(),wait()等函數定義在Object類,而不是Thread類中的原因。

注意:調用wait/notify/notifyAll一定是在擷取對象的鎖之後,否則會報錯哈!java.lang.IllegalMonitorStateException

wait()

方法是將當前線程進入等待(waiting)狀態,同時也會讓當前線程釋放它持有的鎖(同步鎖),直到其他線程調用此對象的notify()活notifyAll(),喚醒當前對象上的線程(單個或所有),讓其進入就緒狀態,等待cpu調度,才能繼續執行wait之後的代碼;

wait(long timeout)

也是讓當前的線程進入等待(TIMED_WAITING)狀態,該方法可以指定逾時時間,當調用此對象的notify()或者NotifyAll(),或者超過指定的時間,則線程也會別喚醒,進入就緒狀態;

wait(long timeout,int naous)

notify()和notifyAll()是喚醒當前對象上的等待線程,notify是喚醒單個線程,而notifyAll則是喚醒所有的線程;

整體流程是這樣:當一個線程擷取對象的同步鎖後,然後執行直到wait()方法,這時該線程進入等待狀態,釋放該對象的同步鎖,這時另外一個線程(喚醒線程)擷取同步鎖後(這裡的同步鎖一定是和等待線程的同步鎖是同一個),執行到notify()或notifyAll()後,才能喚醒等待線程,雖然等待線程被喚醒,但是它不能立刻執行,因為喚醒線程還持有該對象的同步鎖,必須等待喚醒線程釋放了對象的同步鎖之後,等待線程才能擷取對象的同步鎖進而繼續運行。

Thread中方法

yeild(),sleep()都是定義在Thread類中

yeild()

它的作用是讓步,也就是說由正在啟動並執行狀態進入到就緒狀態,從而讓其他具有相同優先順序的線程擷取執行權,但是,並不能保證在當前線程調用yeild方法後,其他線程一定能擷取執行權,也有可能是當前線程再次進入運行狀態繼續執行。

sleep()

讓當前線程休眠,即讓當前線程由運行狀態轉換到阻塞狀態,sleep可指定休眠時間,當線程的休眠時間超過了指定的時間,線程會被喚醒,由阻塞狀態變成就緒裝,然後等待cpu調度。
特別注意,sleep()是不會釋放對象的同步鎖,就是單純的讓線程阻塞。

interrupt()

當線程調用interrupt(),只是設定了線程的中斷狀態,並不會終止線程,剩下的是由你自己來處理該線程怎麼辦,wait(), wait(timeout), join(), sleep(timeout), await(),await(timeout)等方法都是可以被interrupt()方法中斷的。

線程釋放鎖一個是方法執行完、調用wait、代碼拋出異常。

java-線程-基礎

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.