第一章、跟着Calvin瞭解多線程

        說到多線程,在我們現實生活中存在很多廣泛的例子,就拿我本人做個典型案例吧。博主本人相貌出衆,才藝雙全,所以身邊的女性資源可以說是非常豐富,與異性交往可謂是經驗老道。在平時學習之餘,可以和自己心儀的妹子一邊聊騷,一邊聽音樂,興起之時還可以哼幾段小曲,不可謂不快活呀。在這個過程中,博主在同一個時間點可以同時處理很多件事情。其中和妹子聊騷是一個線程,聽音樂是一個線程,哼曲也可以是一個線程,這便是多線程。

        在更進一步地分析多線程的概念之前,我們還需要理清楚兩個專有名詞的區別,即進程線程

        進程:在操作系統中運行的程序就是一個進程,比如快播、探探、陌陌等等。

        線程:一個進程可以有多個線程,如我們看文藝動作片時,在看到女主膚白貌美、溫潤如玉的同時,還能聽到女主魅惑的喘息聲,並且爲了增強用戶體驗度,片子裏還會爲我們顯示中文字幕,這每一項都屬於線程。

        進程和線程的主要區別如下:

區別 進程 線程 描述
根本區別 作爲操作系統資源分配的最小單位 程序執行的最小單位 計算機在執行程序時,會爲程序創建相應的進程,進行資源分配時,是以進程爲單位進行相應的分配。每個進程都有相應的線程,在執行程序時,實際上是執行相應的一系列線程。
開銷 進程間的切換會有較大開銷 線程執行開銷小  
地址空間 進程有自己獨立的地址空間,每啓動一個進程,系統都會爲其分配地址空間,建立數據表來維護代碼段、堆棧段和數據段 線程沒有獨立的地址空間,同一進程的線程共享本進程的地址空間。  
資源擁有 進程之間的資源是獨立的 同一進程內的線程共享本進程的資源  
執行過程 每個獨立的進程程有一個程序運行的入口、順序執行序列和程序入口 線程不能獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。  
注:線程是處理機調度的基本單位,但是進程不是。由於程序執行的過程其實是執行具體的線程,那麼處理機處理的也是程序相應的線程,所以處理機調度的基本單位是線程。很多多線程是模擬出來的,真正的多線程是指一個CPU有多個核心,或者一臺服務器有多個CPU。如果是模擬出來的多線程,在同一個時間點,CPU只能執行一個代碼,因爲線程間切換速度很快,所以纔會有同時執行的錯覺。

        在Java中,分爲兩類線程,即用戶線程(User Thread)和守護線程(Daemon Thread)。我們日常業務開發中編寫的邏輯代碼運行之後,都屬於用戶線程的範疇。而守護線程,類似於操作系統裏面的守護進程。由於Java語言機制是構建在JVM的基礎之上,這一機制意味着Java平臺是把操作系統的進程給屏蔽了。所以需要在JVM裏面構造出對自己有利的機制,於是守護線程應運而生。

所謂的守護線程,指的是程序運行時在後臺提供的一種通用服務的線程。比如垃圾回收線程就是一個很稱職的守護者,並且這種線程並不屬於程序中不可或缺的部分。因此,當所有的非守護線程結束時,程序也就終止了,同時會殺死進程中的所有守護線程。反過來說,只要任何非守護線程還在運行,程序就不會終止。

事實上,User Thread(用戶線程)和Daemon Thread(守護線程)從本質上來說並沒有什麼區別,唯一的不同之處就在於虛擬機的離開:如果用戶線程已經全部退出運行了,只剩下守護線程存在了,虛擬機也就退出了。因爲沒有了被守護者,守護線程也就沒有工作可做了,也就沒有繼續運行程序的必要了。

守護線程並非只有虛擬機內部可以提供,用戶也可以手動將一個用戶線程設定/轉換爲守護線程。

在Thread類中提供了一個setDaemon(true)方法來將一個普通的線程(用戶線程)設置爲守護線程。

        程序運行時即使我們自己沒有創建線程,後臺也會存在多個線程,如GC(垃圾回收)線程、主線程等。

  • 我們通常把main()稱之爲主線程,它是系統的入口,用於執行整個程序。
  • 在一個進程中,如果開闢了多個線程,線程的運行由調度器安排調度,調度器是與操作系統密切相關的,所以線程運行的先後順序是不能人爲干預的。

        那麼聊了這麼多有關多線程的知識點,它究竟有什麼作用呢?使用多線程又會帶來哪些問題?我們在開發過程中又有哪些使用場景呢?博主總結多線程帶來的好處主要有以下幾點:

  • 採用多線程的程序,擁有更快的響應速度。我們在用快播的時候,可以在欣賞一部文藝動作片的同時,下載其他的經典影片。這樣當我們欣賞完一部影片,便可接着欣賞第二部已下載好的影片,觀影過程更爲流暢。
  • 採用多線程可以極大地提高CPU的資源利用率。如果CPU在處理幾項任務時,後面任務的執行必須等在前面的任務執行完,這個等待的過程是非常耗時耗資源的,那麼有了多線程,前面的任務在佔用大量處理資源時,CPU可以通過線程分配資源執行其他任務。

        使用多線程常見的問題

  • 當多個線程對同一份資源進行操作時,會存在資源搶奪的問題,需要加入併發控制。
  • 線程會帶來額外的開銷,如CPU調度時間、併發控制開銷等。
  • 每個線程在自身的工作內存交互,加載和存儲主內存時如果控制不當會造成數據不一致。

        多線程的應用場景

  • 圖片的上傳與下載:我們可以通過瀏覽器同時上傳下載多張圖片
  • 電驢種子下載:我們下載種子時,電驢後臺會同時開啓多個線程,將一個種子分割成多塊,通過多個節點共同完成對一個種子的下載。
  • Web服務器在同一時刻接收多個用戶的請求。

        以上便是博主對於多線程概念的一個理解,由於博主水平有限,難免會存在疏漏。當你發現文中描述不準確或者錯誤的地方,歡迎留言指正。如果覺得博主寫的不錯的,可以點點關注,支持下博主。後續博主會分享個人學習積累下來的一些包括視頻和書籍的技術資源,供大家免費學習使用。沒有高深的知識,沒有進階的技巧,萬丈高樓平地起!讓我們一起在碼農的職業生涯中共勉。       

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章