什麼是上下文切換
即使是單核cpu也支援多執行緒執行**,cpu通過給每個執行緒分配cpu時間片來實現這個機制。時間片是cpu分配給各個執行緒的時間,因為時間片非常短,所以cpu通過不停地切換執行緒執行,讓我們感覺多個執行緒時同時執行的,時間片一般是幾十毫秒(ms)。
cpu通過時間片分配演算法來迴圈執行任務,當前任務執行乙個時間片後會切換到下乙個任務。但是,在切換前會儲存上乙個任務的狀態,以便下次切換回這個任務時,可以再次載入這個任務的狀態,從任務儲存到再載入的過程就是一次上下文切換。
這就像我們同時讀兩本書,當我們在讀一本英文的技術書籍時,發現某個單詞不認識,於是便開啟中英文詞典,但是在放下英文書籍之前,大腦必須先記住這本書讀到了多少頁的第多少行,等查完單詞之後,能夠繼續讀這本書。這樣的切換是會影響讀書效率的,同樣上下文切換也會影響多執行緒的執行速度。
上下文切換**測試
public class contextswitchtest
private static void concurrency() throws exception
}});
thread.start();
int b = 0;
for (long i = 0; i < count; i++)
thread.join();
long time = system.currenttimemillis() - start;
system.out.println("concurrency:" + time + "ms, b = " + b);
}private static void serial()
int b = 0;
for (int i = 0; i < count; i++)
long time = system.currenttimemillis() - start;
system.out.println("serial:" + time + "ms, b = " + b + ", a = " + a);}}
修改上面的count值,即修改迴圈次數,看一下序列執行和併發執行的時間測試結果:
從表中可以看出,100次併發執行累加以下,序列執行和併發執行的執行速度總體而言差不多,1萬次以下序列執行甚至還可以說是略快。為什麼併發執行的速度會比序列慢呢?這就是因為執行緒有建立和上下文切換的開銷。
引起執行緒上下文切換的原因
對於我們經常使用的搶占式作業系統而言,引起執行緒上下文切換的原因大概有以下幾種:
當前執行任務的時間片用完之後,系統cpu正常排程下乙個任務
當前執行任務碰到io阻塞,排程器將此任務掛起,繼續下一任務
多個任務搶占鎖資源,當前任務沒有搶到鎖資源,被排程器掛起,繼續下一任務
使用者**掛起當前任務,讓出cpu時間
硬體中斷
如何減少上下文切換
既然上下文切換會導致額外的開銷,因此減少上下文切換次數便可以提高多執行緒程式的執行效率。減少上下文切換的方法有無鎖併發程式設計、cas演算法、使用最少執行緒和使用協程。
Java學習 多執行緒基礎
2.建立多執行緒方法 3.thread類的常用方法 4.執行緒的排程 5.執行緒的生命週期 6.執行緒的同步機制 synchronized 7.執行緒的通訊 8.生產者與消費者的問題 程序 process 是程式的一次執行過程,或是正在執行的乙個程式。動態過程 有它自身的產生 存在和消亡的過程。執行...
Java 多執行緒學習總結2
併發執行最理想的狀況是讓一些 毫不相干 的somebody 自己做自己的事情,和別人無關。但是事實讓確非如此,因為在哲學上講,世界是乙個整體,每個個體之間都存在聯絡,我們讓一些東西不相干,是我們人類為了簡化問題,而從概念上進行的分割劃分,呵呵。事實上,如果某個somebody 為多個執行緒共享,其中...
Java 多執行緒學習總結3
執行緒的死鎖 如果多個執行緒操作多個物件互相請求,那麼會引起死鎖。package deadlock public class somebody public synchronized void saysomething catch interruptedexception e other.sings...