1. 程式人生 > >執行緒阻塞的原因

執行緒阻塞的原因

        執行緒在執行的過程中因為某些原因而發生阻塞,阻塞狀態的執行緒的特點是:該執行緒放棄CPU的使用,暫停執行,只有等到導致阻塞的原因消除之後才回復執行。或者是被其他的執行緒中斷,該執行緒也會退出阻塞狀態,同時丟擲InterruptedException。

        導致阻塞的原因有很多種,大致分為三種來討論,分別是一般執行緒中的阻塞,Socket客戶端的阻塞,Socket伺服器端的阻塞。

一般執行緒中的阻塞:

        A、執行緒執行了Thread.sleep(int millsecond);方法,當前執行緒放棄CPU,睡眠一段時間,然後再恢復執行

        B、執行緒執行一段同步程式碼,但是尚且無法獲得相關的同步鎖,只能進入阻塞狀態,等到獲取了同步鎖,才能回覆執行。

        C、執行緒執行了一個物件的wait()方法,直接進入阻塞狀態,等待其他執行緒執行notify()或者notifyAll()方法。

        D、執行緒執行某些IO操作,因為等待相關的資源而進入了阻塞狀態。比如說監聽system.in,但是尚且沒有收到鍵盤的輸入,則進入阻塞狀態。

Socket客戶端的阻塞:

        A、請求與伺服器連線時,呼叫connect方法,進入阻塞狀態,直至連線成功。

        B、當從Socket輸入流讀取資料時,在讀取足夠的資料之前會進入阻塞狀態。比如說通過BufferedReader類使用readLine()方法時,在沒有讀出一行資料之前,資料量就不算是足夠,會處在阻塞狀態下。

        C、呼叫Socket的setSoLinger()方法關閉了Socket延遲,當執行Socket的close方法時,會進入阻塞狀態,知道底層Socket傳送完所有的剩餘資料

Socket伺服器的阻塞:

        A、執行緒執行ServerSocket的accept()方法,等待客戶的連線,知道接收到客戶的連線,才從accept方法中返回一個Socket物件

        B、從Socket輸入流讀取資料時,如果輸入流沒有足夠的資料,就會進入阻塞狀態

        D、執行緒向Socket的輸出流寫入一批資料,可能進入阻塞狀態

        當程式阻塞時,會降低程式的效率,於是人們就希望能引入非阻塞的操作方法。    

        所謂非阻塞方法,就是指當執行緒執行這些方法時,如果操作還沒有就緒,就立即返回,不會阻塞著等待操作就緒。Java.nio 提供了這些支援非阻塞通訊的類。