程式與執行緒的區別 :
(1)一個執行緒只屬於一個程式,一個程式可以有多個執行緒
(2)程式間相互獨立,執行緒共享程式的記憶體空間和資源
(3)程式是分配資源的單位,有獨立的地址空間
(4)執行緒是處理器排程的基本單位
程式間通訊的幾種方式:
(1)管道。半雙工通訊方式,常用於有親緣關係的父子程式
(2)命名管道。用於沒有親緣關係的程式
(3)訊息佇列。存放在核心,克服訊號和管道的缺點
(4)共享記憶體。一個程式建立,多個程式共享,通常與訊號量一起使用,實現程式間的通訊與同步
(5)訊號。通知某個事件發生
(6)訊號量,是一個計數器,用來控制多程式對共享資源的訪問,是一種鎖機制,解決程式間的互斥與同步
為什麼使用多執行緒
使用多執行緒,可以把一些大任務分解成多個小任務來執行,多個小任務之間互不影像,同時進行,這樣,充分利用了cpu資源。
實現多執行緒的兩種方式:
(1)繼承Thread類,重寫run方法;
(2)實現Runable介面,實現run方法;
執行緒的狀態:
新建,就緒,執行,阻塞,死亡
執行緒池的作用:
(1)降低資源消耗,可重複利用
(2)加快響應速度,不需要重複建立
(3)便於管理
spring 中的執行緒池
Spring中的執行緒池是由ThreadPoolTaskExecutor類來實現的
Java程式碼初始化:
private void test2(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(15);
executor.setKeepAliveSeconds(1);
executor.setQueueCapacity(5);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
executor.execute(new Runnable(){
@Override
public void run() {
//執行的程式碼
}
});
}
複製程式碼
執行緒通訊
1.通訊方式
(1)等待通知機制:兩個執行緒通過對同一物件呼叫等待wait()和通知notify()方法來進行通訊
案例:兩個執行緒交替列印奇偶數 深入理解執行緒通訊
(2)join()方法:其實也是呼叫等待通知機制
(3)volatile共享記憶體:java採用共享記憶體的方式進行同信(也可以使用管道)
(4)執行緒響應中斷
(5)執行緒池的awaitTermination() 方法
(6)管道通訊
volatile關鍵字
典型案例:i++和++i不是原子操作
作用:保證記憶體可見性和防止 JVM 進行指令重排優化 volatile關鍵字詳解
解釋:cpu的速度往往與記憶體的速度很難匹配,所以在cpu和記憶體之間加入快取記憶體(每個執行緒都有自己的快取記憶體),在cpu沒有命中快取記憶體的時候才會去記憶體中取,在併發程式設計中就會出現快取記憶體沒有同步到記憶體中的情況。
用volatile修飾的變數會強制任何執行緒對此變數的操作都會立即重新整理到主記憶體中,並且強制讓快取了此變數的棧清空,必須從主記憶體中獲取資料,保證了一致性(注意,修飾之後並不是讓執行緒從主記憶體中取,依然將變數拷貝到快取區)。所以可以保證取出的值一定是最新的,但是注意:volatile並不保證原子性,不保證執行緒安全性