我理解的Java併發基礎(一):一些基本概念

1,什麼是併發?
  在cpu角度講,多個cpu的核同時在工做。從Java的角度將,JVM在同一時刻在處理多個線程的請求。html

2,爲何要併發?
  併發適用於多核處理器,以解決單線程阻塞致使效率低的問題,儘量利用cpu空閒等待時間。java

  缺點:線程間的切換具備額外開銷。(用戶線程的上下文要複製到cpu線程上來執行)api

3,cpu、進程、線程的關係
  cpu:執行計算機指令
  操做系統的進程:程序的一次執行
  操做系統的線程:操做系統調度器的調度的基本單位,交由cpu執行
  cpu的線程:存放要執行的數據、指令等,是cpu的基本執行單位跨域

  處理器的線程,與操做系統的進程,是 N:N 的關係。
  操做系統的進程,與操做系統的線程,是1:N的關係。
  因此,處理器線程與操做系統線程之間是 N:N 的關係。
  一個進程至少有一個線程。線程不能跨域進程與訪問另外一個進程的內容。緩存

備註:
  一般cpu的線程和核心數對應,幾核就是幾線程。可是單個線程並不能讓單個cpu核滿載形成cpu浪費,因而有了超線程技術,即一個cpu核負責兩個或多個線程的運行。安全

4,多線程的使用方式
  多線程的使用有兩種:協同式和搶佔式。
  協同式的實現比較簡單,因爲是在當前線程主動觸發其餘線程並等待結果返回,對調用者來講是能夠感知的,不存在線程安全問題。缺點是等待的過程是阻塞的,線程阻塞會形成必定程度的浪費性能。好比Lua。而Java採用搶佔式。多線程

5,多線程爭奪cpu使用權
  cpu的基本調度單位是線程,由一個叫作「調度器(scheduler)」的操做系統的組件來調度。cpu的核會在一個 時間片 內執行用戶線程的操做。調度器會根據線程的優先級和線程的飢餓程度(等待時間)兩個因素來調度線程。併發

6,Java的線程與進程
  jvm的線程與進程,是對操做系統的線程與進程的一種封裝,方便操做。jvm

  jvm將操做系統的進程,封裝爲Process(抽象類),惟一實現類是ProcessImpl。有建立工具類ProcessBuilder。jvm對進程的封裝提供很是少的api,由於制定者不主張在java中以建立進程的方式執行多任務。函數

  jvm將操做系統的線程,封裝爲Runable接口,java.lang包下有兩個實現類,Thread和Shutdown。Shutdown是用來執行JVM關閉的時候的鉤子函數的。普通代碼實際運行的時候,須要一個Thread類的對象來.start()來執行。這個.start()是一個synchronized方法,方法內部會調用native的.start0()交給操做執行。Thread類還提供不少native的方法來供調用。

  java.concurrent包下有Callable接口,能夠有返回值(Future模式)。

7,線程的緩存與一致性規範
  計算機的cpu的運算速度與內存的讀寫速度相差好幾個數量級,所以引入了高速緩存。每一個cpu的線程單獨配一個高速緩存。
  帶來的問題:緩存一致性(CacheCoherence)。爲了解決緩存一致性的問題,要求各個處理器訪問緩存時遵循必定的協議(好比:MESI協議)。
  Java虛擬機有本身的內存模型,虛擬機經過操做系統能夠操做cpu的線程和高速緩存,因此Java內存模型定義瞭如何解決緩存一致性的規範。

8,線程間的數據通信
  協同式自然具有線程間的通信能力。Java採用搶佔式,線程只與主內存交互。若是線程間須要通信的話,須要先將數據從線程本身的工做內存寫回到主內存,另一個線程再從主內容加載到它的線程。
  每個java線程擁有本身的工做內存,全部的java線程共用一個主內存。

方便理解:
  主內存對應java堆中的對象實例數據部分,物理硬件的主內存。
  工做內存對應虛擬機棧中的部分區域,程序運行時主要訪問讀寫的是工做內存。
  這種理解是片面的不許確的,但剛接觸的時候比較容易理解一些。

參考資料:

相關文章
相關標籤/搜索