一、volatile介紹
volatile是一個(gè)類型修飾符(type specifier),就像大家更熟悉的const一樣,它是被設(shè)計(jì)用來修飾被不同線程訪問和修改的變量。volatile的作用是作為指令關(guān)鍵字,確保本條指令不會(huì)因編譯器的優(yōu)化而省略,且要求每次直接讀值。volatile的變量是說這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。
volatile作用:
簡(jiǎn)單地說就是防止編譯器對(duì)代碼進(jìn)行優(yōu)化。比如如下程序:
4XBYTE[2]=0x55;
XBYTE[2]=0x56;
XBYTE[2]=0x57;
XBYTE[2]=0x58;
對(duì)外部硬件而言,上述四條語(yǔ)句分別表示不同的操作,會(huì)產(chǎn)生四種不同的動(dòng)作,但是編譯器卻會(huì)對(duì)上述四條語(yǔ)句進(jìn)行優(yōu)化,認(rèn)為只有XBYTE[2]=0x58(即忽略前三條語(yǔ)句,只產(chǎn)生一條機(jī)器代碼)。如果鍵入volatile,則編譯器會(huì)逐一地進(jìn)行編譯并產(chǎn)生相應(yīng)的機(jī)器代碼(產(chǎn)生四條代碼)。
正確使用volatile變量的條件:
只能在有限的一些情形下使用 volatile變量替代鎖。要使 volatile變量提供理想的線程安全,必須同時(shí)滿足下面兩個(gè)條件:
● 對(duì)變量的寫操作不依賴于當(dāng)前值。
● 該變量沒有包含在具有其他變量的不變式中。
實(shí)際上,這些條件表明,可以被寫入 volatile變量的這些有效值獨(dú)立于任何程序的狀態(tài),包括變量的當(dāng)前狀態(tài)。
第一個(gè)條件的限制使 volatile變量不能用作線程安全計(jì)數(shù)器。雖然增量操作(x++)看上去類似一個(gè)單獨(dú)操作,實(shí)際上它是一個(gè)由讀?。薷模瓕懭氩僮餍蛄薪M成的組合操作,必須以原子方式執(zhí)行,而 volatile 不能提供必須的原子特性。實(shí)現(xiàn)正確的操作需要使 x 的值在操作期間保持不變,而 volatile變量無法實(shí)現(xiàn)這點(diǎn)。(然而,如果將值調(diào)整為只從單個(gè)線程寫入,那么可以忽略第一個(gè)條件。)
大多數(shù)編程情形都會(huì)與這兩個(gè)條件的其中之一沖突,使得 volatile變量不能像 synchronized 那樣普遍適用于實(shí)現(xiàn)線程安全。清單 1 顯示了一個(gè)非線程安全的數(shù)值范圍類。它包含了一個(gè)不變式 —— 下界總是小于或等于上界。
二、多線程的介紹
多線程(英語(yǔ):multithreading),是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的技術(shù)。具有多線程能力的計(jì)算機(jī)因有硬件支持而能夠在同一時(shí)間執(zhí)行多于一個(gè)線程,進(jìn)而提升整體處理性能。具有這種能力的系統(tǒng)包括對(duì)稱多處理機(jī)、多核心處理器以及芯片級(jí)多處理(Chip-level multithreading)或同時(shí)多線程(Simultaneous multithreading)處理器。[1] 在一個(gè)程序中,這些獨(dú)立運(yùn)行的程序片段叫作“線程”(Thread),利用它編程的概念就叫作“多線程處理(Multithreading)”。具有多線程能力的計(jì)算機(jī)因有硬件支持而能夠在同一時(shí)間執(zhí)行多于一個(gè)線程(***譯作“執(zhí)行緒”),進(jìn)而提升整體處理性能。
多線程用途:
用途在大多數(shù)研究領(lǐng)域內(nèi)是要求線程調(diào)度程序要能夠快速選擇其中一個(gè)已就緒線程去運(yùn)行,而不是一個(gè)一個(gè)運(yùn)行而降低效率。所以要讓調(diào)度程序去分辨線程的優(yōu)先級(jí)是很重要的。而線程調(diào)度程序可能是以硬件、軟件,或是軟硬件并存的形式存在。
多線程的優(yōu)點(diǎn):
使用線程可以把占據(jù)時(shí)間長(zhǎng)的程序中的任務(wù)放到后臺(tái)去處理
用戶界面可以更加吸引人,這樣比如用戶點(diǎn)擊了一個(gè)按鈕去觸發(fā)某些事件的處理,可以彈出一個(gè)進(jìn)度條來顯示處理的進(jìn)度·
程序的運(yùn)行速度可能加快
在一些等待的任務(wù)實(shí)現(xiàn)上如用戶輸入、文件讀寫和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等,線程就比較有用了。在這種情況下可以釋放一些珍貴的資源如內(nèi)存占用等等
多線程技術(shù)在IOS軟件開發(fā)中也有舉足輕重的位置
多線程的缺點(diǎn):
如果有大量的線程,會(huì)影響性能,因?yàn)?a target="_blank">操作系統(tǒng)需要在它們之間切換。
更多的線程需要更多的內(nèi)存空間。
線程可能會(huì)給程序帶來更多“bug”,因此要小心使用。
線程的中止需要考慮其對(duì)程序運(yùn)行的影響。
通常塊模型數(shù)據(jù)是在多個(gè)線程間共享的,需要防止線程死鎖情況的發(fā)生。
三、多線程中volatile使用的理解
package com.casking.cdds.modules.test.web;
public class Counter {
//volatile關(guān)鍵字能保證多個(gè)內(nèi)存塊中的引用值是最新的可見性,不能保證原子性。可見性只能保證每次讀取的是最新的值,但是volatile沒辦法保證對(duì)變量的操作的原子性。
public volatile static int count = 0;
public synchronized static void inc() {
// 這里延遲1秒,使得結(jié)果明顯
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
count++;
}
public static void main(String[] args) {
// 同時(shí)啟動(dòng)1000個(gè)線程,去進(jìn)行i++計(jì)算,看看實(shí)際結(jié)果
for (int i = 0; i 《 1000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
}
}).start();
}
// 方法返回活動(dòng)線程的當(dāng)前線程的線程組中的數(shù)量---主線程下
while (Thread.activeCount() 》 1) // 保證前面的線程都執(zhí)行完
Thread.yield(); //當(dāng)一個(gè)線程使用了這個(gè)方法之后,它就會(huì)把自己CPU執(zhí)行的時(shí)間讓掉,讓自己或者其它的線程運(yùn)行。
// 這里每次運(yùn)行的值都有可能不同,可能為1000
System.out.println(“運(yùn)行結(jié)果:Counter.count=” + Counter.count);
}
}
評(píng)論
查看更多