多線程是爲了提高CPU的處理效率,也即提高程序的執行效率而引進的。因爲在操作系統中CUP,內存,硬盤(IO設備)3者之間存在處理速度上的顯著差異這是硬件層面無法解決的矛盾。CPU的處理速度>內存>硬盤(IO設備),爲了平衡和內存之間速度差異cpu中引入了緩存,爲了能分時複用cpu引入了多線程。
多線程常用的實現方式有,繼承Thread類和實現Runnable接口。
在單條件(condition)場景下實現線程的互斥和同步,可以使用synchronized,wait(),notify(),notifyAll()等來實現,在需要線程互斥訪問資源的地方使用synchronized修飾,線程間同步也即線程間如何通信的可以利用,wait(),notify(),notifyAll() 例如當某個條件不滿足時:while(條件不滿足){
Thread.wait();
}
當條件滿足時利用notify或者notifyAll,通知線程。如果沒有特殊要求的場景,推薦使用notifyAll來進行線程的喚醒,notify喚醒可能有些線程永遠沒有機會喚醒。
Thread.join(),該方法的意思是,在主線程中執行這個方法會讓主線程阻塞來等待子線程執行完才進行下一步操作。比如在某個場景下,有3個資源需要利用3個線程分別去獲取,主線程利用各個子線程的join()方法來等待子線程執行完相應的資源獲取功能。
volatile 關鍵字是爲了在多線程場景下,對同一個變量讀寫的可見性,他會告訴編譯器對這個變量的讀寫不能使用cpu緩存,而必須使用內存。
java中線程的生命週期:
1.NEW(初始化狀態)
2.RUNNABLE(可運行 / 運行狀態)
3.BLOCKED(阻塞狀態)
4.WAITING(無時限等待)
5.TIMED_WAITING(有時限等待)
6.TERMINATED(終止狀態)
狀態可以簡化爲上圖
在java.util.concurrent包中包含了很多多線程處理的工具類,下面我來簡單介紹下:
1.Lock ,Condition
Lock支持多個特性:1.能夠響應中斷,2.支持超時,3.非阻塞地獲取鎖
// 支持中斷的API
void lockInterruptibly()
throws InterruptedException;
// 支持超時的API
boolean tryLock(long time, TimeUnit unit)
throws InterruptedException;
// 支持非阻塞獲取鎖的API
boolean tryLock();
使用範式:
lass X {
private final Lock rtl = new ReentrantLock(); int value;
public void addOne() {
// 獲取鎖 rtl.lock(); try { value+=1; } finally { // 保證鎖能釋放 rtl.unlock(); } }
}
condition :條件變量,在MESA管程模型中條件變量有自己的條件變量隊列,管程實現了對共享變量的互斥和同步操作,當某個線程想要對共享變量V執行操作時,可能有兩個條件變量A,B相應的會有兩個條件變量隊列。