但是volatile不能保證原子性,也就不能保證線程安全。
1,可見性
可見性指的是在一個線程中對該變量的修改會馬上由工作內存(Work Memory)寫回主內存(Main Memory),所以會馬上反應在其它線程的讀取操作中。順便一提,工作內存和主內存可以近似理解爲實際電腦中的高速緩存和主存,工作內存是線程獨享的,主存是線程共享的。
2,禁止指令重排序優化
禁止指令重排序優化。大家知道我們寫的代碼(尤其是多線程代碼),由於編譯器優化,在實際執行的時候可能與我們編寫的順序不同。編譯器只保證程序執行結果與源代碼相同,卻不保證實際指令的順序與源代碼相同。這在單線程看起來沒什麼問題,然而一旦引入多線程,這種亂序就可能導致嚴重問題。volatile關鍵字就可以從語義上解決這個問題。
題目說拋出一個異常,但是沒說具體是什麼異常,那麼就要分情況了:
1.如果拋出一個FileNotFoundException(或其子類),那麼最終結果就打印FileNotFoundException
2.如果拋出一個IOException,或者IOException的子類(不包含FileNotFoundException及其子類),那麼最終結果就打印IOException
3.如果拋出一個Exception(不包含IOException及其子類),那麼最終結果就打印Exception.
以上,所以3個皆有可能.但是,不管是哪一種情況,只會輸出其中之一。
從答案上來看,B,C,D的輸出情況是不存在的。因此選A
- 粉紅色的是受檢查的異常(checked exceptions),其必須被 try{}catch語句塊所捕獲,或者在方法簽名裏通過throws子句聲明.受檢查的異常必須在編譯時被捕捉處理,命名爲 Checked Exception 是因爲Java編譯器要進行檢查,Java虛擬機也要進行檢查,以確保這個規則得到遵守.
- 綠色的異常是運行時異常(runtime exceptions),需要程序員自己分析代碼決定是否捕獲和處理,比如 空指針,被0除…
- 而聲明爲Error的,則屬於嚴重錯誤,如系統崩潰、虛擬機錯誤、動態鏈接失敗等,這些錯誤無法恢復或者不可能捕捉,將導致應用程序中斷,Error不需要捕捉。
import java.util.*;
public class Main3 {
public int[] exchangeAB(int[] AB) {
AB[0] = AB[0]-AB[1];
AB[1] = AB[0]+AB[1];
AB[0] = AB[1]-AB[0];
return AB;
}
}
import java.util.*;
public class Main4 {
public String[] getGray(int n) {
if(n==1){
return new String[]{"0","1"};
}
String[] s1=getGray(n-1);//遞歸調用
String[] s2=new String[2*s1.length];
for(int i=0;i<s1.length;i++){
s2[i]="0"+s1[i];//首位添加0
s2[i+s1.length]="1"+s1[s1.length-1-i];//首位添加1,注意需要順序反向
}
return s2;
}