五分鐘看穿Java併發相關概念,併發原來如此簡單

本文主要對Java併發(Concurrent)相關的概念進行說明。算法

1.進程(Process)與線程(Thread)

  1. 進程是系統資源分配的最小單元。線程是CPU調度的最小單元。
  2. 一個 進程至少包含一個線程,能夠包含多個線程。這些線程共享這個進程的資源。
  3. 每一個線程都擁有獨立的運行棧和程序計數器,線程切換開銷小。
  4. 多進程指的是操做系統同時運行多個程序,如當前操做系統中同時運行着QQ、IE、微信等程序。
  5. 多線程指的是同一進程中同時運行多個線程,如迅雷運行時,能夠開啓多個線程,同時進行多個文件的下載。

    2.並行(Parallel)、併發(Concurrent)與多線程(Multithreading)

  6. 並行是指多個任務在同一時刻進行。併發是指多個任務在同一時間段內發生。
  7. 並行是物理上的同時發生,而併發是邏輯上的同時發生。
  8. 體如今程序上: 並行是指多個CPU內核在同一時刻,同時運行多個任務。併發是指單個CPU內,經過CPU調度算法,讓用戶感受在同時運行多個任務。
  9. 更形象的說法: 並行是指兩隊人員同時使用兩臺咖啡機。併發是指兩隊人員交替使用同一臺咖啡機。—-Erlang 之父 Joe Armstrong。

五分鐘看穿Java併發相關概念,併發原來如此簡單

  1. 多線程即多個線程,通常只多個同時在運行的單線程。
  2. 若是是在單核CPU上,多線程確定是併發運行的。若是是在多核CPU上,這些多線程也多是並行運行。

    3.線程安全

    線程安全,指的是在併發的狀況之下,線程的調度順序不影響運行結果。編程

如不加鎖控制的轉帳操做,在單線程運行中是安全的,可是在多線程環境中,確定是不安全的。
這裏只給出示例,具體邏輯就沒不解釋了。安全

void transferMoney(User from, User to, float amount){
    to.setMoney(to.getBalance() + amount);
    from.setMoney(from.getBalance() - amount);
}

4.死鎖

死鎖是指兩個或更多線程阻塞着等待其它處於死鎖狀態的線程所持有的鎖。微信

例如,多線程

  • 若是線程1鎖住了A,而後嘗試對B進行加鎖,同時線程2已經鎖住了B,接着嘗試對A進行加鎖,這時死鎖就發生了。
  • 線程1永遠得不到B,線程2也永遠得不到A,而且它們永遠也不會知道發生了這樣的事情。
  • 爲了獲得彼此的對象(A和B),它們將永遠阻塞下去。這種狀況就是一個死鎖。

    5.併發優勢

    5.1.資源利用率高

    假定場景:須要從本地讀取和處理兩個文件,讀取一個文件須要5秒,處理一個文件須要2秒。
    單線程:併發

5秒讀取文件A
2秒處理文件A
5秒讀取文件B
2秒處理文件B
---------------------
總共須要14秒

多線程:ide

5秒讀取文件A
5秒讀取文件B + 2秒處理文件A
2秒處理文件B
---------------------
總共須要12秒

總結:操作系統

  • 在等待磁盤讀取文件的時候,CPU大部分時間是空閒的。
  • 利用多線程編程,能夠在磁盤讀取文件的CPU空閒時間內作一些其餘的事情。
  • 因此說, 使用多線程資源利用率更高。

5.2.程序響應更快

一個桌面應用程序存在多個按鈕。點擊這些按鈕,能夠分別進行一些耗時的工做。線程

單線程:設計

每次點擊一個按鈕,都會進行一項耗時的工做。必須等待此項工做完成以後,才能繼續監聽用戶操做。這時,用戶才能點擊其餘按鈕,進行其餘的工做。這樣的應用程序,對用戶而言,響應十分慢,體驗度不好。

多線程:

每次點擊一個按鈕,都會啓動一個子線程去進行這項耗時的工做,主線程繼續監聽用戶操做。這種狀況下,用戶能夠快速的分別點擊須要處理的按鈕。這樣的應用程序,對用戶而言,響應很快,體驗度很好。

6.併發缺點

6.1.設計開發更復雜

線程之間的交互每每很是複雜。 不正確的線程同步產生的錯誤很是難以發現,而且難以重現、難以修復。

6.2.增長額外資源消耗

多線程開發會產生額外的資源消耗,主要來源於三個方面:

  • 線程自己須要消耗一些資源進行本地堆棧的維持與管理。
  • 線程之間切換會致使的上下文切換(Context Switch)開銷。
  • 多線程的管理對CPU來講又是一筆開銷。

因此,因爲多線程會增長額外的資源消耗,對多線程程序而言,線程並非越多就會越快,過多的線程返回會致使程序變慢。

相關文章
相關標籤/搜索