一. 什么是上下文切換?
多線程編程中一般線程的個數都大于 CPU 核心的個數,而一個 CPU 核心在任意時刻只能被一個線程使用。為了讓這些線程都能得到有效執行,CPU 采取的策略是為每個線程分配時間片并輪轉的形式。當一個線程的時間片用完的時候就會重新處于就緒狀態讓給其他線程使用,這個過程就屬于一次上下文切換。
概括來說就是:
當前任務在執行完 CPU 時間片切換到另一個任務之前會先保存自己的狀態,以便下次再切換回這個任務時,可以再加載這個任務的狀態。任務從保存到再加載的過程就是一次上下文切換。
上下文切換通常是計算密集型的。也就是說,它需要相當可觀的處理器時間,在每秒幾十上百次的切換中,每次切換都需要納秒量級的時間。所以,上下文切換對系統來說意味著消耗大量的 CPU 時間,事實上,可能是操作系統中時間消耗最大的操作。
Linux 相比與其他操作系統(包括其他類 Unix 系統)有很多的優點,其中有一項就是,其上下文切換和模式切換的時間消耗非常少。
二. 什么是CAS
1. CAS實現原理
CAS是Compare And Swap的縮寫,意思就是比較并交換。它是無鎖化的實現,是經典的樂觀鎖。
synchronized是一種悲觀鎖,會導致其它所有需要鎖的線程掛起,等待持有鎖的線程釋放鎖。
樂觀鎖就是不加鎖而是假設沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功為止。樂觀鎖的機制就是CAS。
CAS操作很簡單,它包含三個操作數:內存地址V、預期原值A、新值B。先比較內存地址V處的值和預期原值A是否相等,如果相等就將內存地址V處更新為新值B。在配合循環使用時,若CAS操作失敗,會循環執行或到達某個終止處。此操作配合循環使用時,又稱為自旋鎖的實現方式。
2. CAS存在的問題
2.1 ABA問題
解決辦法:
加時間戳
加版本號
2.2 循環開銷大
CAS是樂觀鎖,如果線程比較多,資源搶占激烈,命中率低的情況下,不斷的循環會不斷的消耗資源。實際上,可以設置最大循環數,達到最大循環數還沒有占有資源就自動放棄,避免無限的循環。
2.3 只能保證一個共享變量的原子操作
三. 創建線程池有哪幾個核心參數? 如何合理配置線程池的大小?
1. 核心參數
2. 核心說明
1當線程池中線程數量小于 corePoolSize 則創建線程,并處理請求。
2當線程池中線程數量大于等于 corePoolSize 時,則把請求放入 workQueue 中,隨著線程池 中的核心線程們不斷執行任務,只要線程池中有空閑的核心線程,線程池就從 workQueue 中取 任務并處理。
3當 workQueue 已存滿,放不下新任務時則新建非核心線程入池,并處理請求直到線程數目 達到 maximumPoolSize(最大線程數量設置值)。
4如果線程池中線程數大于 maximumPoolSize 則使用 RejectedExecutionHandler 來進行任 務拒絕處理。
3. 線程池大小分配
線程池究竟設置多大要看你的線程池執行的什么任務了,CPU密集型、IO密集型、混合型,任 務類型不同,設置的方式也不一樣。
任務一般分為:CPU密集型、IO密集型、混合型,對于不同類型的任務需要分配不同大小的線 程池。
3.1 CPU密集型
盡量使用較小的線程池,一般Cpu核心數+1
3.2 IO密集型
方法一:可以使用較大的線程池,一般CPU核心數 * 2
方法二:(線程等待時間與線程CPU時間之比 + 1)* CPU數目
3.3 混合型
可以將任務分為CPU密集型和IO密集型,然后分別使用不同的線程池去處理,按情況而定。
更多關于“Java培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓經驗,課程大綱更科學更專業,有針對零基礎的就業班,有針對想提升技術的好程序員班,高品質課程助力你實現java程序員夢想。