進程是資源分配的最小單位,線程是CPU調度的最小單位java
總結:c++
實現方式有三種算法
實現的方式主要有三種:編程
鎖池EntryList:假設線程A已經得到了某個對象(不是類)的鎖,而其餘線程B,C想要調用這個對象的某個synchronized方法(或者塊),因爲B,C線程在進入對象的synchronized方法以前必須得到該對象鎖的擁有權,而恰巧該對象的鎖恰好被線程A所佔用,此時B,C線程就會被阻塞,進入一個地方去等待鎖的釋放,這個地方就是鎖池。數組
等待池WaitSet:假設線程A調用了某個對象的wait()方法,線程A就會釋放該對象的鎖,同時線程A就進入到了該對象的等待池中,進入到等待池中的線程不會去競爭該對象的鎖。緩存
當調用Thread.yeild()函數時,會給線程調度器一個當前線程願意讓出CPU使用的暗示,可是線程調度器可能會忽略這個暗示。並不會讓出當前線程的鎖。安全
join方法可使得一個線程在另外一個線程結束後再執行。當前線程將阻塞直到這個線程實例完成了再執行。多線程
已經被拋棄的方法:併發
目前使用的方法:app
線程安全出現的緣由:
解決線程安全的根本辦法:同一時刻有且只有一個線程在操做共享數據,其餘線程必須等到該線程處理完數據以後再對共享數據進行操做,引入了互斥鎖
互斥鎖的特性:
根據獲取的鎖分類:
synchronized底層實現原理:
鎖的內存語義:
synchronized的四種狀態:
AQS提供了一種實現阻塞鎖和一系列依賴FIFO等待隊列的同步器的框架,AbstractQueuedSynchronizer中對state的操做是原子的,且不能被繼承。全部的同步機制的實現均依賴於對改變量的原子操做。爲了實現不一樣的同步機制,咱們須要建立一個非共有的(non-public internal)擴展了AQS類的內部輔助類來實現相應的同步邏輯,AbstractQueuedSynchronizer並不實現任何同步接口,它提供了一些能夠被具體實現類直接調用的一些原子操做方法來重寫相應的同步邏輯。AQS同時提供了互斥模式(exclusive)和共享模式(shared)兩種不一樣的同步邏輯。
本質上有兩大類:共享內存機制和消息通訊機制。
java內存模型(即Java Memory Model,簡稱JMM)自己是一種抽象的概念,並不真實的存在,它描述一組規範或者規則,經過這組規範定義了程序中各個變量的訪問方式。
JMM中的主內存:
JMM中的工做內存:
JMM與java內存區域劃分是不一樣的概念層次:
JMM如何解決可見性問題:
compare and swap:
爲何要使用線程池
J.U.C的三個Executor接口
線程池的狀態:
線程池的大小如何選定:
線程池的參數
線程池的任務提交:線程池框架提供了兩種方式提交任務,根據不一樣的業務需求選擇不一樣的方式。
線程池任務的執行:具體的執行流程以下:
addWoker方法實現的前半部分:
一、判斷線程池的狀態,若是線程池的狀態值大於或等SHUTDOWN,則不處理提交的任務,直接返回;
二、經過參數core判斷當前須要建立的線程是否爲核心線程,若是core爲true,且當前線程數小於corePoolSize,則跳出循環,開始建立新的線程,具體實現以下:
線程池的工做線程經過Woker類實現,在ReentrantLock鎖的保證下,把Woker實例插入到HashSet後,並啓動Woker中的線程,其中Worker類設計以下:
runWorker方法是線程池的核心:
getTask實現:
Future和Callable實現:在實際業務場景中,Future和Callable基本是成對出現的,Callable負責產生結果,Future負責獲取結果。
協程(Coroutine)這個詞其實有不少叫法,好比有的人喜歡稱爲纖程(Fiber),或者綠色線程(GreenThread)。其實究其本質,對於協程最直觀的解釋是線程的線程。雖然讀上去有點拗口,但本質上就是這樣。
協程的核心在於調度那塊由他來負責解決,遇到阻塞操做,馬上放棄掉,而且記錄當前棧上的數據,阻塞完後馬上再找一個線程恢復棧並把阻塞的結果放到這個線程上去跑,這樣看上去好像跟寫同步代碼沒有任何差異,這整個流程能夠稱爲coroutine,而跑在由coroutine負責調度的線程稱爲Fiber。
早期,在JVM上實現協程通常會使用kilim,不過這個工具已經好久不更新了,如今經常使用的工具是Quasar,而本文章會所有基於Quasar來介紹。