并發程式設計的目的是為了讓程式運作的更快,但是并不是啟動更多的線程就能讓程式最大限度的并發執行。線程是java語言中重要的功能,它簡化了複雜系統的開發。線程也被稱為輕量級程序,在大多數現代作業系統中,都是以線程為基本排程機關的,而不是程序。
并發的簡史:在早期的計算機中不包含作業系統,它們從頭到尾隻執行一個程式,并且這個程式可以通路計算機中的所有資源。這樣不僅難以編寫和運作程式,而且造成資源的極大浪費。作業系統的出現使得計算機可以每次運作多個程式,并且不同的程式都在單獨的程序中運作:作業系統為每個獨立的程序配置設定各種資源,包括記憶體,檔案句柄以及安全證書等。如果需要的話,在不同的程序間可以通過一些粗粒度的通信機制來交換資料,包括:套接字,信号處理器,共享記憶體,信号量以及檔案等。
使用線程有什麼優勢呢?1.發揮多處理器的強大能力。2.模組化的簡單性。3.異步事件的簡化處理。4.響應更靈敏的使用者界面。當然線程也有風險,都有什麼風險呢?1.安全性問題(非常複雜的問題) 2.活躍性問題。3.性能問題。在多線程的程式中當線程排程器臨時挂起活躍線程并轉而運作另一個線程,就會頻繁的出現上下文切換操作,這種操作将會帶來極大的開銷。
什麼是上下文切換呢?CPU通過時間片配置設定算法來循環執行任務,目前任務執行一個時間片後會切換到下一個任務。但是在切換前會儲存上一個任務的狀态,以便下次切換回這個任務時可以再加載這個任務的狀态。是以任務從儲存到再夾雜物i的過程就是一次上下文的切換。但是使用多線程一定快嗎?下面的程式驗證一下:
package chapterOne;
/**
* @author acer
* 對比串行與并發消耗的時間
*/
public class ConcurrencyTest {
private static final long count = l;
public static void main(String[] args) {
try {
concurrency();
} catch (InterruptedException e) {
e.printStackTrace();
}
serial();
}
/**
* 使用并發執行
* @throws InterruptedException
*/
public static void concurrency() throws InterruptedException{
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
int a = ;
for(long i=;i<count;i++) {
a += ;
}
}
});
thread.start();
int b = ;
for(long i=;i<count;i++) {
b--;
}
thread.join();
long time = System.currentTimeMillis()-start;
System.out.println("concurrency:"+time);
}
public static void serial(){
long start = System.currentTimeMillis();
int a = ;
for(long i=;i<count;i++) {
a += ;
}
int b = ;
for(long i=;i<count;i++) {
b--;
}
long time = System.currentTimeMillis();
System.out.println("serial:"+time);
}
}
運作結果是串行0 并發1.可以并不是并發就一定快。這是因為有線程的建立以及上下文切換的開銷。ime);
“`
運作結果是串行0 并發1.可以并不是并發就一定快。這是因為有線程。
何減少上下文的切換呢?常用的方法有一下幾種。1.無鎖并發程式設計 2.CAS算法 3.使用最少線程和使用協程。第一次使用這個編輯器,有點不大熟,這篇部落格下文接着。