Thread和Runnable的區別

NiceToMeetYou發表於2019-04-28

多執行緒的實現有兩種方式,一種是繼承thread,還有一種是實現Runnable介面,推薦使用後者,因為java是單繼承,如果繼承了thread之後,就無法繼承其他類了。顯然RUnnable更加靈活一點。

實現Runnable,比之thread的優勢:

  • 避免由於java單繼承帶來的侷限性。
  • 相比於繼承thread更能描述資料共享的概念。

無論是實現Runnable還是繼承Thread的方法來實現多執行緒,他的啟動都是從start開始的,而不是在run方法。如果呼叫了run,那麼run方法內部的程式碼塊實際上還是執行在當前執行緒的。

理由: 當啟動一個執行緒的時候,作業系統會為其分配資源,在start方法中不僅執行了多執行緒的程式碼,除此還呼叫了start0方法,該方法的宣告是native額,在java語言中有一種技術叫做jni,即JavaNativeInterface,該技術的特點是呼叫本機作業系統提供的函式,但是有一個缺點是不能離開特定的作業系統,如果執行緒需要執行,必須有作業系統去分配資源,所以此操作是JVM根據不同的作業系統實現的。

如果多執行緒是通過實現Runnable來實現的,此時與繼承thread實現有一個區別,那就是Runnable沒有start方法,而多執行緒必須由start方法啟動,所以這裡必須呼叫Thread類的一個構造方法Thread(RUnnable target), 該構造方法得到了Runnable介面的一個實現,於是就可以通過呼叫start方法開啟多執行緒了。

訊息機制主要指的是Handler的執行機制,它的執行需要底層的MessageQueue和Looper支撐,MessageQueue以佇列的形式對外提供插入和刪除的工作,雖然叫訊息佇列,但是實際上是採用的單連結串列的資料結構來儲存訊息的。

實現Runnable

class MyRUnnable() : Runnable {
    override fun run() {
        //...程式碼邏輯
        
        val msg: Message = Message.obtain()
        handler.post(msg)
    }
}
複製程式碼

啟動多執行緒

val thread = Thread(MyRunnable())
thread.start()
複製程式碼

處理多執行緒的返回

val handler = object: Handler() {
    override fun handlerMessage(msg: Message?) {
        msg?.let {
            ///...邏輯程式碼
        }
    }
}
複製程式碼

相關文章