版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、自增(+)和自減(-)運(yùn)算符 我們先來(lái)回答幾個(gè)問(wèn)題吧: Java代碼 1. int i = 0; 2. int j = i+; 3. int k = -i; int i = 0;int j = i+;int k = -i;這段代碼運(yùn)行后,i等于多少?j等于多少?k等于多少?太簡(jiǎn)單了?好,繼續(xù): Java代碼 1. int i = 0; 2. int j =
2、 i+ + +i; 3. int k = -i + i-; int i = 0;int j = i+ + +i;int k = -i + i-;代碼執(zhí)行后i、j、k分別等于多少呢?還是很簡(jiǎn)單?好,再繼續(xù): Java代碼 1. int i=0; 2. System.out.println(i+); int i=0;System.out.println(i+);這段代碼運(yùn)行后輸出結(jié)果是什么?0?1? Java代
3、碼 1. float f=0.1F; 2. f+; 3. double d=0.1D; 4. d+; 5. char c='a' 6. c+; float f=0.1F;f+;double d=0.1D;d+;char c='a'c+;上面這段代碼可以編譯通過(guò)嗎?為什么?如果你能順利回答到這里,說(shuō)明你對(duì)自增和自減運(yùn)算符的掌握已經(jīng)很好了。 為了分析出上面提出的幾個(gè)問(wèn)題,我們首先來(lái)回顧
4、一下相關(guān)知識(shí): · 自增(+):將變量的值加1,分前綴式(如+i)和后綴式(如i+)。前綴式是先加1再使用;后綴式是先使用再加1。 · 自減(-):將變量的值減1,分前綴式(如-i)和后綴式(如i-)。前綴式是先減1再使用;后綴式是先使用再減1。 在第一個(gè)例子中,int j=i+;是后綴式,因此i的值先被賦予j,然后再自增1,所以這行代碼運(yùn)行后,i=1、j=0;而int k=-i;是前綴式,因此i先自減1,然后再將它的值賦予k,因此這行代碼運(yùn)行后,i=0、k=0。 在第二個(gè)例子中,對(duì)于int j=i+ + +i;,首先運(yùn)行i+,i的值0被用于加運(yùn)算(+),之后i自增值變?yōu)?
5、,然后運(yùn)行+i,i先自增變?yōu)?,之后被用于加運(yùn)算,最后將i兩次的值相加的結(jié)果0+2=2賦給j,因此這行代碼運(yùn)行完畢后i=2、j=2;對(duì)于int k=-i + i-;用一樣的思路分析,具體過(guò)程在此不再贅述,結(jié)果應(yīng)該是i=0、k=2。 自增與自減運(yùn)算符還遵循以下規(guī)律: 1. 可以用于整數(shù)類(lèi)型byte、short、int、long,浮點(diǎn)類(lèi)型float、double,以及字符串類(lèi)型char。 2. 在Java5.0及以上版本中,它們可以用于基本類(lèi)型對(duì)應(yīng)的包裝器類(lèi)Byte、Short、Integer、Long、Float、Double、Character。 3. 它們的運(yùn)算結(jié)果的類(lèi)型與被運(yùn)算的變量的類(lèi)型
6、相同。 下面的這個(gè)例子驗(yàn)證以上列出的規(guī)律,它可以編譯通過(guò)并執(zhí)行。 Java代碼 1. public class Test 2. public static void main(String args) 3. / 整型 4.
7、 byte b = 0; 5. b+; 6. / 整型 7. long l = 0; 8.
8、 l+; 9. / 浮點(diǎn)型 10. double d = 0.0; 11. d+; 1
9、2. / 字符串 13. char c = 'a' 14. c+; 15. /
10、160;基本類(lèi)型包裝器類(lèi) 16. Integer i = new Integer(0); 17. i+; 18. 19. public class Test public static v
11、oid main(String args) / 整型byte b = 0;b+;/ 整型long l = 0;l+;/ 浮點(diǎn)型double d = 0.0;d+;/ 字符串char c = 'a'c+;/ 基本類(lèi)型包裝器類(lèi)Integer i = new Integer(0);i+;按位運(yùn)算符 你還能說(shuō)出來(lái)按位運(yùn)算符一共有哪幾種嗎?對(duì)比下面的列表看看,有沒(méi)有從你的記憶中消失了的: 1. 按位與運(yùn)算(&):二元運(yùn)算符。當(dāng)被運(yùn)算的兩個(gè)值都為1時(shí),運(yùn)算結(jié)果為1;否則為0。 2. 按位或運(yùn)算(|):二元運(yùn)算符。當(dāng)被運(yùn)算的兩個(gè)值都為0時(shí),運(yùn)算結(jié)果為0;否則為1。 3. 按位異或運(yùn)算
12、():二元運(yùn)算符。當(dāng)被運(yùn)算的兩個(gè)值中任意一個(gè)為1,另一個(gè)為0時(shí),運(yùn)算結(jié)果為1;否則為0。 4. 按位非運(yùn)算():一元運(yùn)算符。當(dāng)被運(yùn)算的值為1時(shí),運(yùn)算結(jié)果為0;當(dāng)被運(yùn)算的值為0時(shí),運(yùn)算結(jié)果為1。 這里不像我們看到的邏輯運(yùn)算符(與運(yùn)算&&、或運(yùn)算|、非運(yùn)算?。┎僮鞯氖遣紶栔祎rue或false,或者是一個(gè)能產(chǎn)生布爾值的表達(dá)式;“按位運(yùn)算符”所指的“位”就是二進(jìn)制位,因此它操作的是二進(jìn)制的0和1。在解釋按位運(yùn)算符的執(zhí)行原理時(shí),我們順便說(shuō)說(shuō)它們和邏輯運(yùn)算符的區(qū)別。 list=1 · 邏輯運(yùn)算符只能操作布爾值或者一個(gè)能產(chǎn)生布爾值的表達(dá)式;按位運(yùn)算符能操作整型值,包括byte、s
13、hort、int、long,但是不能操作浮點(diǎn)型值(即float和double),它還可以操作字符型(char)值。按位運(yùn)算符不能夠操作對(duì)象,但是在Java5.0及以上版本中,byte、short、int、long、char所對(duì)應(yīng)的包裝器類(lèi)是個(gè)例外,因?yàn)镴AVA虛擬機(jī)會(huì)自動(dòng)將它們轉(zhuǎn)換為對(duì)應(yīng)的基本類(lèi)型的數(shù)據(jù)。 下面的例子驗(yàn)證了這條規(guī)律: Java代碼 1. public class BitOperatorTest 2. public static void mai
14、n(String args) 3. / 整型 4. byte b1 = 10, b2 = 20; 5. System.out.println(
15、"(byte)10 & (byte)20 = " + (b1 & b2); 6. / 字符串型 7. char c1 = 'a', c2 = 'A
16、' 8. System.out.println("(char)a | (char)A = " + (c1 | c2); 9. / 基本類(lèi)型的包裝器類(lèi) 10.
17、60; Long l1 = new Long(555), l2 = new Long(666); 11. System.out.println("(Long)555 (Long)666 = " + (l1 l2); 12.
18、; / 浮點(diǎn)型 13. float f1 = 0.8F, f2 = 0.5F; 14. / 編譯報(bào)錯(cuò),按位運(yùn)算符不能用于浮點(diǎn)數(shù)類(lèi)型 15.
19、160; / System.out.println("(float)0.8 & (float)0.5 = " + (f1 & f2); 16. 17. public class BitOperatorTest public static void main(String args) /
20、整型byte b1 = 10, b2 = 20;System.out.println("(byte)10 & (byte)20 = " + (b1 & b2);/ 字符串型char c1 = 'a', c2 = 'A'System.out.println("(char)a | (char)A = " + (c1 | c2);/ 基本類(lèi)型的包裝器類(lèi)Long l1 = new Long(555), l2 = new Long(666);System.out.println("(Long)555 (Lo
21、ng)666 = " + (l1 l2);/ 浮點(diǎn)型float f1 = 0.8F, f2 = 0.5F;/ 編譯報(bào)錯(cuò),按位運(yùn)算符不能用于浮點(diǎn)數(shù)類(lèi)型/ System.out.println("(float)0.8 & (float)0.5 = " + (f1 & f2);運(yùn)行結(jié)果: · (byte)10 & (byte)20 = 0 · (char)a | (char)A = 97 · (Long)555 (Long)666 = 177 · 邏輯運(yùn)算符的運(yùn)算遵循短路形式,而按位運(yùn)算符則不是。所謂短路就
22、是一旦能夠確定運(yùn)算的結(jié)果,就不再進(jìn)行余下的運(yùn)算。下面的例子更加直觀地展現(xiàn)了短路與非短路的區(qū)別: Java代碼 1. public class OperatorTest 2. public boolean leftCondition() 3. System.out.println("執(zhí)行-返回值:false;方法:leftCond
23、ition()"); 4. return false; 5. 6. 7. public boolean rightCondition() 8.
24、0; System.out.println("執(zhí)行-返回值:true;方法:rightCondition()"); 9. return true; 10. 11. 12. public int leftNumber()
25、; 13. System.out.println("執(zhí)行-返回值:0;方法:leftNumber()"); 14. return 0; 15. 16. 17. pu
26、blic int rightNumber() 18. System.out.println("執(zhí)行-返回值:1;方法:rightNumber()"); 19. return 1; 20. 21
27、. 22. public static void main(String args) 23. OperatorTest ot = new OperatorTest(); 24. 25. &
28、#160; if (ot.leftCondition() && ot.rightCondition() 26. / do something 27. 28.
29、; System.out.println(); 29. 30. int i = ot.leftNumber() & ot.rightNumber(); 31. 32. public class Operato
30、rTest public boolean leftCondition() System.out.println("執(zhí)行-返回值:false;方法:leftCondition()");return false;public boolean rightCondition() System.out.println("執(zhí)行-返回值:true;方法:rightCondition()");return true;public int leftNumber() System.out.println("執(zhí)行-返回值:0;方法:leftNumber()"
31、;);return 0;public int rightNumber() System.out.println("執(zhí)行-返回值:1;方法:rightNumber()");return 1;public static void main(String args) OperatorTest ot = new OperatorTest();if (ot.leftCondition() && ot.rightCondition() / do somethingSystem.out.println();int i = ot.leftNumber() & ot.
32、rightNumber();運(yùn)行結(jié)果: · 執(zhí)行-返回值:false;方法:leftCondition() · 執(zhí)行-返回值:0;方法:leftNumber() · 執(zhí)行-返回值:1;方法:rightNumber() 運(yùn)行結(jié)果已經(jīng)很明顯地顯示了短路和非短路的區(qū)別,我們一起來(lái)分析一下產(chǎn)生這個(gè)運(yùn)行結(jié)果的原因。當(dāng)運(yùn)行“ot.leftCondition() && ot.rightCondition()”時(shí),由于方法leftCondition()返回了false,而對(duì)于“&&”運(yùn)算來(lái)說(shuō),必須要運(yùn)算符兩邊的值都為true時(shí),運(yùn)算結(jié)果才為true
33、,因此這時(shí)候就可以確定,不論rightCondition()的返回值是什么,“ot.leftCondition() && ot.rightCondition()”的運(yùn)算值已經(jīng)可以確定是false,由于邏輯運(yùn)算符是短路的形式,因此在這種情況下,rightCondition()方法就不再被運(yùn)行了。 而對(duì)于“ot.leftNumber() & ot.rightNumber()”,由于“l(fā)eftNumber()”的返回值是0,對(duì)于按位運(yùn)算符“&”來(lái)說(shuō),必須要運(yùn)算符兩邊的值都是1時(shí),運(yùn)算結(jié)果才是1,因此這時(shí)不管“rightNumber()”方法的返回值是多少,“ot.le
34、ftNumber() & ot.rightNumber()”的運(yùn)算結(jié)果已經(jīng)可以確定是0,但是由于按位運(yùn)算符是非短路的,所以rightNumber()方法還是被執(zhí)行了。這就是短路與非短路的區(qū)別。 /list 移位運(yùn)算符 移位運(yùn)算符和按位運(yùn)算符一樣,同屬于位運(yùn)算符,因此移位運(yùn)算符的位指的也是二進(jìn)制位。它包括以下幾種: 1. 左移位(<<):將操作符左側(cè)的操作數(shù)向左移動(dòng)操作符右側(cè)指定的位數(shù)。移動(dòng)的規(guī)則是在二進(jìn)制的低位補(bǔ)0。 2. 有符號(hào)右移位(>>):將操作符左側(cè)的操作數(shù)向右移動(dòng)操作符右側(cè)指定的位數(shù)。移動(dòng)的規(guī)則是,如果被操作數(shù)的符號(hào)為正,則在二進(jìn)制的高位補(bǔ)0;如果被操
35、作數(shù)的符號(hào)為負(fù),則在二進(jìn)制的高位補(bǔ)1。 3. 無(wú)符號(hào)右移位(>>>):將操作符左側(cè)的操作數(shù)向右移動(dòng)操作符右側(cè)指定的位數(shù)。移動(dòng)的規(guī)則是,無(wú)論被操作數(shù)的符號(hào)是正是負(fù),都在二進(jìn)制位的高位補(bǔ)0。 注意,移位運(yùn)算符不存在“無(wú)符號(hào)左移位(<<<)”一說(shuō)。與按位運(yùn)算符一樣,移位運(yùn)算符可以用于byte、short、int、long等整數(shù)類(lèi)型,和字符串類(lèi)型char,但是不能用于浮點(diǎn)數(shù)類(lèi)型float、double;當(dāng)然,在Java5.0及以上版本中,移位運(yùn)算符還可用于byte、short、int、long、char對(duì)應(yīng)的包裝器類(lèi)。我們可以參照按位運(yùn)算符的示例寫(xiě)一個(gè)測(cè)試程序來(lái)驗(yàn)證
36、,這里就不再舉例了。 與按位運(yùn)算符不同的是,移位運(yùn)算符不存在短路不短路的問(wèn)題。 寫(xiě)到這里就不得不提及一個(gè)在面試題中經(jīng)常被考到的題目: 引用請(qǐng)用最有效率的方法計(jì)算出2乘以8等于幾? 這里所謂的最有效率,實(shí)際上就是通過(guò)最少、最簡(jiǎn)單的運(yùn)算得出想要的結(jié)果,而移位是計(jì)算機(jī)中相當(dāng)基礎(chǔ)的運(yùn)算了,用它來(lái)實(shí)現(xiàn)準(zhǔn)沒(méi)錯(cuò)了。左移位“<<”把被操作數(shù)每向左移動(dòng)一位,效果等同于將被操作數(shù)乘以2,而2*8=(2*2*2*2),就是把2向左移位3次。因此最有效率的計(jì)算2乘以8的方法就是“2<<3”。 最后,我們?cè)賮?lái)考慮一種情況,當(dāng)要移位的位數(shù)大于被操作數(shù)對(duì)應(yīng)數(shù)據(jù)類(lèi)型所能表示的最大位數(shù)時(shí),結(jié)果會(huì)是怎樣呢
37、?比如,1<<35=?呢? 這里就涉及到移位運(yùn)算的另外一些規(guī)則: 1. byte、short、char在做移位運(yùn)算之前,會(huì)被自動(dòng)轉(zhuǎn)換為int類(lèi)型,然后再進(jìn)行運(yùn)算。 2. byte、short、int、char類(lèi)型的數(shù)據(jù)經(jīng)過(guò)移位運(yùn)算后結(jié)果都為int型。 3. long經(jīng)過(guò)移位運(yùn)算后結(jié)果為long型。 4. 在左移位(<<)運(yùn)算時(shí),如果要移位的位數(shù)大于被操作數(shù)對(duì)應(yīng)數(shù)據(jù)類(lèi)型所能表示的最大位數(shù),那么先將要求移位數(shù)對(duì)該類(lèi)型所能表示的最大位數(shù)求余后,再將被操作數(shù)移位所得余數(shù)對(duì)應(yīng)的數(shù)值,效果不變。比如1<<35=1<<(35%32)=1<<3=8。
38、 5. 對(duì)于有符號(hào)右移位(>>)運(yùn)算和無(wú)符號(hào)右移位(>>>)運(yùn)算,當(dāng)要移位的位數(shù)大于被操作數(shù)對(duì)應(yīng)數(shù)據(jù)類(lèi)型所能表示的最大位數(shù)時(shí),那么先將要求移位數(shù)對(duì)該類(lèi)型所能表示的最大位數(shù)求余后,再將被操作數(shù)移位所得余數(shù)對(duì)應(yīng)的數(shù)值,效果不變。比如100>>35=100>>(35%32)=100>>3=12。 下面的測(cè)試代碼驗(yàn)證了以上的規(guī)律: Java代碼 1. public abstract class Test 2. public
39、 static void main(String args) 3. System.out.println("1 << 3 = " + (1 << 3); 4. System.out
40、.println("(byte) 1 << 35 = " + (byte) 1 << (32 + 3); 5. System.out.println("(short) 1 << 35 = " + (short)&
41、#160;1 << (32 + 3); 6. System.out.println("(char) 1 << 35 = " + (char) 1 << (32 + 3); 7.
42、; System.out.println("1 << 35 = " + (1 << (32 + 3); 8. System.out.println("1L << 67 = " + (1L <&
43、lt; (64 + 3); 9. / 此處需要Java5.0及以上版本支持 10. System.out.println("new Integer(1) << 3 = " + (new Integer(1
44、) << 3); 11. System.out.println("10000 >> 3 = " + (10000 >> 3); 12. System.out.println("10000
45、160;>> 35 = " + (10000 >> (32 + 3); 13. System.out.println("10000L >>> 67 = " + (10000L >>> (64 + 3
46、); 14. 15. public abstract class Test public static void main(String args) System.out.println("1 << 3 = " + (1 << 3);System.out.println("(byte) 1 << 35 = " + (byte) 1 << (32 + 3);System.out.pr
47、intln("(short) 1 << 35 = " + (short) 1 << (32 + 3);System.out.println("(char) 1 << 35 = " + (char) 1 << (32 + 3);System.out.println("1 << 35 = " + (1 << (32 + 3);System.out.println("1L << 67 = " + (1L << (64 + 3)
48、;/ 此處需要Java5.0及以上版本支持System.out.println("new Integer(1) << 3 = " + (new Integer(1) << 3);System.out.println("10000 >> 3 = " + (10000 >> 3);System.out.println("10000 >> 35 = " + (10000 >> (32 + 3);System.out.println("10000L >&g
49、t;> 67 = " + (10000L >>> (64 + 3);運(yùn)行結(jié)果: 1. 1 << 3 = 8 2. (byte) 1 << 35 = 8 3. (short) 1 << 35 = 8 4. (char) 1 << 35 = 8 5. 1 << 35 = 8 6. 1L << 67 = 8 7. new Integer(1) << 3 = 8 8. 10000 >> 3 = 1250 9. 10000 >> 35 = 1250 10. 100
50、00L >>> 67 = 1250 下一期預(yù)告:JAVA面試題解惑系列(十二)你真的了解數(shù)組嗎? · 11:00 · 瀏覽 (111) · 評(píng)論 (0) · 分類(lèi): java筆試面試 2009-07-01縮略顯示JAVA筆試面試必考題系列(十)話說(shuō)多線程JAVA面試題解惑系列(十)話說(shuō)多線程關(guān)鍵字: java 面試題 多線程 thread 線程池 synchronized 死鎖作者:臧圩人(zangweiren) 網(wǎng)址: >>>轉(zhuǎn)載請(qǐng)注明出處!<<< 線程或者說(shuō)多線程,是我們處理多任務(wù)的強(qiáng)大工具。線程
51、和進(jìn)程是不同的,每個(gè)進(jìn)程都是一個(gè)獨(dú)立運(yùn)行的程序,擁有自己的變量,且不同進(jìn)程間的變量不能共享;而線程是運(yùn)行在進(jìn)程內(nèi)部的,每個(gè)正在運(yùn)行的進(jìn)程至少有一個(gè)線程,而且不同的線程之間可以在進(jìn)程范圍內(nèi)共享數(shù)據(jù)。也就是說(shuō)進(jìn)程有自己獨(dú)立的存儲(chǔ)空間,而線程是和它所屬的進(jìn)程內(nèi)的其他線程共享一個(gè)存儲(chǔ)空間。線程的使用可以使我們能夠并行地處理一些事情。線程通過(guò)并行的處理給用戶帶來(lái)更好的使用體驗(yàn),比如你使用的郵件系統(tǒng)(outlook、Thunderbird、foxmail等),你當(dāng)然不希望它們?cè)谑杖⌒锣]件的時(shí)候,導(dǎo)致你連已經(jīng)收下來(lái)的郵件都無(wú)法閱讀,而只能等待收取郵件操作執(zhí)行完畢。這正是線程的意義所在。 實(shí)現(xiàn)線程的方式 實(shí)現(xiàn)
52、線程的方式有兩種: 1. 繼承java.lang.Thread,并重寫(xiě)它的run()方法,將線程的執(zhí)行主體放入其中。 2. 實(shí)現(xiàn)java.lang.Runnable接口,實(shí)現(xiàn)它的run()方法,并將線程的執(zhí)行主體放入其中。 這是繼承Thread類(lèi)實(shí)現(xiàn)線程的示例: Java代碼 1. public class ThreadTest extends Thread 2. public void run() 3.
53、60; / 在這里編寫(xiě)線程執(zhí)行的主體 4. / do something 5. 6. public class ThreadTest extends Thread public void run() / 在這里編寫(xiě)線程執(zhí)行的主體/ do
54、something這是實(shí)現(xiàn)Runnable接口實(shí)現(xiàn)多線程的示例: Java代碼 1. public class RunnableTest implements Runnable 2. public void run() 3. / 在這里編寫(xiě)線程執(zhí)行的主體 4.
55、; / do something 5. 6. public class RunnableTest implements Runnable public void run() / 在這里編寫(xiě)線程執(zhí)行的主體/ do something這兩種實(shí)現(xiàn)方式的區(qū)別并不大。繼承Thread類(lèi)的方式實(shí)現(xiàn)起來(lái)較為簡(jiǎn)單,但是繼承它的類(lèi)就不能再繼承別的類(lèi)了,因此也就不能繼承別的類(lèi)的有用的方法了。而使用是
56、想Runnable接口的方式就不存在這個(gè)問(wèn)題了,而且這種實(shí)現(xiàn)方式將線程主體和線程對(duì)象本身分離開(kāi)來(lái),邏輯上也較為清晰,所以推薦大家更多地采用這種方式。 如何啟動(dòng)線程 我們通過(guò)以上兩種方式實(shí)現(xiàn)了一個(gè)線程之后,線程的實(shí)例并沒(méi)有被創(chuàng)建,因此它們也并沒(méi)有被運(yùn)行。我們要啟動(dòng)一個(gè)線程,必須調(diào)用方法來(lái)啟動(dòng)它,這個(gè)方法就是Thread類(lèi)的start()方法,而不是run()方法(既不是我們繼承Thread類(lèi)重寫(xiě)的run()方法,也不是實(shí)現(xiàn)Runnable接口的run()方法)。run()方法中包含的是線程的主體,也就是這個(gè)線程被啟動(dòng)后將要運(yùn)行的代碼,它跟線程的啟動(dòng)沒(méi)有任何關(guān)系。上面兩種實(shí)現(xiàn)線程的方式在啟動(dòng)時(shí)會(huì)有
57、所不同。 繼承Thread類(lèi)的啟動(dòng)方式: Java代碼 1. public class ThreadStartTest 2. public static void main(String args) 3. / 創(chuàng)建一個(gè)線程實(shí)例 4. &
58、#160; ThreadTest tt = new ThreadTest(); 5. / 啟動(dòng)線程 6. tt.start(); 7. 8. p
59、ublic class ThreadStartTest public static void main(String args) / 創(chuàng)建一個(gè)線程實(shí)例ThreadTest tt = new ThreadTest();/ 啟動(dòng)線程tt.start();實(shí)現(xiàn)Runnable接口的啟動(dòng)方式: Java代碼 1. public class RunnableStartTest 2. public static void main(String args)
60、60; 3. / 創(chuàng)建一個(gè)線程實(shí)例 4. Thread t = new Thread(new RunnableTest(); 5. / 啟動(dòng)線程
61、60; 6. t.start(); 7. 8. public class RunnableStartTest public static void main(String args) / 創(chuàng)建一個(gè)線程實(shí)例Thread t = new Thread(new RunnableTest();/ 啟動(dòng)線程t.start();實(shí)際上這兩種啟動(dòng)線程的方式原理是一樣的。首先都是調(diào)用本地方
62、法啟動(dòng)一個(gè)線程,其次是在這個(gè)線程里執(zhí)行目標(biāo)對(duì)象的run()方法。那么這個(gè)目標(biāo)對(duì)象是什么呢?為了弄明白這個(gè)問(wèn)題,我們來(lái)看看Thread類(lèi)的run()方法的實(shí)現(xiàn): Java代碼 1. public void run() 2. if (target != null) 3. target.run(); 4. &
63、#160; 5. public void run() if (target != null) target.run();當(dāng)我們采用實(shí)現(xiàn)Runnable接口的方式來(lái)實(shí)現(xiàn)線程的情況下,在調(diào)用new Thread(Runnable target)構(gòu)造器時(shí),將實(shí)現(xiàn)Runnable接口的類(lèi)的實(shí)例設(shè)置成了線程要執(zhí)行的主體所屬的目標(biāo)對(duì)象target,當(dāng)線程啟動(dòng)時(shí),這個(gè)實(shí)例的run()方法就被執(zhí)行了。當(dāng)我們采用繼承Thread的方式實(shí)現(xiàn)線程時(shí),線程的這個(gè)run()方法被重寫(xiě)了,所以當(dāng)線程啟動(dòng)時(shí),執(zhí)行的是這個(gè)對(duì)象自身的run
64、()方法。總結(jié)起來(lái)就一句話,線程類(lèi)有一個(gè)Runnable類(lèi)型的target屬性,它是線程啟動(dòng)后要執(zhí)行的run()方法所屬的主體,如果我們采用的是繼承Thread類(lèi)的方式,那么這個(gè)target就是線程對(duì)象自身,如果我們采用的是實(shí)現(xiàn)Runnable接口的方式,那么這個(gè)target就是實(shí)現(xiàn)了Runnable接口的類(lèi)的實(shí)例。 線程的狀態(tài) 在Java 1.4及以下的版本中,每個(gè)線程都具有新建、可運(yùn)行、阻塞、死亡四種狀態(tài),但是在Java 5.0及以上版本中,線程的狀態(tài)被擴(kuò)充為新建、可運(yùn)行、阻塞、等待、定時(shí)等待、死亡六種。線程的狀態(tài)完全包含了一個(gè)線程從新建到運(yùn)行,最后到結(jié)束的整個(gè)生命周期。線程狀態(tài)的具體信息
65、如下: 1. NEW(新建狀態(tài)、初始化狀態(tài)):線程對(duì)象已經(jīng)被創(chuàng)建,但是還沒(méi)有被啟動(dòng)時(shí)的狀態(tài)。這段時(shí)間就是在我們調(diào)用new命令之后,調(diào)用start()方法之前。 2. RUNNABLE(可運(yùn)行狀態(tài)、就緒狀態(tài)):在我們調(diào)用了線程的start()方法之后線程所處的狀態(tài)。處于RUNNABLE狀態(tài)的線程在JAVA虛擬機(jī)(JVM)上是運(yùn)行著的,但是它可能還正在等待操作系統(tǒng)分配給它相應(yīng)的運(yùn)行資源以得以運(yùn)行。 3. BLOCKED(阻塞狀態(tài)、被中斷運(yùn)行):線程正在等待其它的線程釋放同步鎖,以進(jìn)入一個(gè)同步塊或者同步方法繼續(xù)運(yùn)行;或者它已經(jīng)進(jìn)入了某個(gè)同步塊或同步方法,在運(yùn)行的過(guò)程中它調(diào)用了某個(gè)對(duì)象繼承自java.
66、lang.Object的wait()方法,正在等待重新返回這個(gè)同步塊或同步方法。 4. WAITING(等待狀態(tài)):當(dāng)前線程調(diào)用了java.lang.Object.wait()、java.lang.Thread.join()或者java.util.concurrent.locks.LockSupport.park()三個(gè)中的任意一個(gè)方法,正在等待另外一個(gè)線程執(zhí)行某個(gè)操作。比如一個(gè)線程調(diào)用了某個(gè)對(duì)象的wait()方法,正在等待其它線程調(diào)用這個(gè)對(duì)象的notify()或者notifyAll()(這兩個(gè)方法同樣是繼承自O(shè)bject類(lèi))方法來(lái)喚醒它;或者一個(gè)線程調(diào)用了另一個(gè)線程的join()(這個(gè)方法屬
67、于Thread類(lèi))方法,正在等待這個(gè)方法運(yùn)行結(jié)束。 5. TIMED_WAITING(定時(shí)等待狀態(tài)):當(dāng)前線程調(diào)用了java.lang.Object.wait(long timeout)、java.lang.Thread.join(long millis)、java.util.concurrent.locks.LockSupport.packNanos(long nanos)、java.util.concurrent.locks.LockSupport.packUntil(long deadline)四個(gè)方法中的任意一個(gè),進(jìn)入等待狀態(tài),但是與WAITING狀態(tài)不同的是,它有一個(gè)最大等待時(shí)間,即
68、使等待的條件仍然沒(méi)有滿足,只要到了這個(gè)時(shí)間它就會(huì)自動(dòng)醒來(lái)。 6. TERMINATED(死亡狀態(tài)、終止?fàn)顟B(tài)):線程完成執(zhí)行后的狀態(tài)。線程執(zhí)行完run()方法中的全部代碼,從該方法中退出,進(jìn)入TERMINATED狀態(tài)。還有一種情況是run()在運(yùn)行過(guò)程中拋出了一個(gè)異常,而這個(gè)異常沒(méi)有被程序捕獲,導(dǎo)致這個(gè)線程異常終止進(jìn)入TERMINATED狀態(tài)。 在Java5.0及以上版本中,線程的全部六種狀態(tài)都以枚舉類(lèi)型的形式定義在java.lang.Thread類(lèi)中了,代碼如下: Java代碼 1. public enum State 2.
69、; NEW, 3. RUNNABLE, 4. BLOCKED, 5. WAITING, 6. TIMED_WAITING, 7. TERMINATED; 8.
70、; public enum State NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;sleep()和wait()的區(qū)別 sleep()方法和wait()方法都成產(chǎn)生讓當(dāng)前運(yùn)行的線程停止運(yùn)行的效果,這是它們的共同點(diǎn)。下面我們來(lái)詳細(xì)說(shuō)說(shuō)它們的不同之處。 sleep()方法是本地方法,屬于Thread類(lèi),它有兩種定義: Java代碼 1. public static native void sleep(long millis) throws Interru
71、ptedException; 2. 3. public static void sleep(long millis, int nanos) throws InterruptedException 4. /other code 5. public static native void sleep(long millis)
72、 throws InterruptedException;public static void sleep(long millis, int nanos) throws InterruptedException /other code其中的參數(shù)millis代表毫秒數(shù)(千分之一秒),nanos代表納秒數(shù)(十億分之一秒)。這兩個(gè)方法都可以讓調(diào)用它的線程沉睡(停止運(yùn)行)指定的時(shí)間,到了這個(gè)時(shí)間,線程就會(huì)自動(dòng)醒來(lái),變?yōu)榭蛇\(yùn)行狀態(tài)(RUNNABLE),但這并不表示它馬上就會(huì)被運(yùn)行,因?yàn)榫€程調(diào)度機(jī)制恢復(fù)線程的運(yùn)行也需要時(shí)間。調(diào)用sleep()方法并不會(huì)讓線程釋放它所持有的同步鎖;而且在這期間它也不會(huì)阻礙其
73、它線程的運(yùn)行。上面的連個(gè)方法都聲明拋出一個(gè)InterruptedException類(lèi)型的異常,這是因?yàn)榫€程在sleep()期間,有可能被持有它的引用的其它線程調(diào)用它的interrupt()方法而中斷。中斷一個(gè)線程會(huì)導(dǎo)致一個(gè)InterruptedException異常的產(chǎn)生,如果你的程序不捕獲這個(gè)異常,線程就會(huì)異常終止,進(jìn)入TERMINATED狀態(tài),如果你的程序捕獲了這個(gè)異常,那么程序就會(huì)繼續(xù)執(zhí)行catch語(yǔ)句塊(可能還有finally語(yǔ)句塊)以及以后的代碼。 為了更好地理解interrupt()效果,我們來(lái)看一下下面這個(gè)例子: Java代碼 1. public class
74、InterruptTest 2. public static void main(String args) 3. Thread t = new Thread() 4.
75、; public void run() 5. try 6. &
76、#160; System.out.println("我被執(zhí)行了-在sleep()方法前"); 7. / 停止運(yùn)行10分鐘 8.
77、0; Thread.sleep(1000 * 60 * 10); 9. System.out.println("我被執(zhí)行了-在sleep()方法后"); &
78、#160; 10. catch (InterruptedException e) 11. Syst
79、em.out.println("我被執(zhí)行了-在catch語(yǔ)句塊中"); 12. 13. System.out.println("我被
80、執(zhí)行了-在try語(yǔ)句塊后"); 14. 15. 16. / 啟動(dòng)線程 17.
81、; t.start(); 18. / 在sleep()結(jié)束前中斷它 19. errupt(); 20. 21. public class InterruptTest publ
82、ic static void main(String args) Thread t = new Thread() public void run() try System.out.println("我被執(zhí)行了-在sleep()方法前");/ 停止運(yùn)行10分鐘Thread.sleep(1000 * 60 * 10);System.out.println("我被執(zhí)行了-在sleep()方法后"); catch (InterruptedException e) System.out.println("我被執(zhí)行了-在catch語(yǔ)句塊中");S
83、ystem.out.println("我被執(zhí)行了-在try語(yǔ)句塊后");/ 啟動(dòng)線程t.start();/ 在sleep()結(jié)束前中斷它errupt();運(yùn)行結(jié)果: 1. 我被執(zhí)行了-在sleep()方法前 2. 我被執(zhí)行了-在catch語(yǔ)句塊中 3. 我被執(zhí)行了-在try語(yǔ)句塊后 wait()方法也是本地方法,屬于Object類(lèi),有三個(gè)定義: Java代碼 1. public final void wait() throws InterruptedException 2. &
84、#160; /do something 3. 4. 5. public final native void wait(long timeout) throws InterruptedException; 6. 7. public final void wait(long timeout, int nanos) throws InterruptedException 8. /do something 9. public final void wait() throws InterruptedException /do somethingpublic final native void wait(long timeout) throws Interrupted
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度個(gè)性化美發(fā)店服務(wù)股份制合作合同4篇
- 二零二五版新能源汽車(chē)充電樁投資分紅合同3篇
- 2025年倉(cāng)儲(chǔ)租賃協(xié)議審核
- 二零二五年度木地板工程環(huán)保認(rèn)證與施工合同4篇
- 2025年民用航空器租賃合規(guī)審查協(xié)議
- 2025年度綠色校園綠植種植與教育推廣合同4篇
- 2024 年浙江公務(wù)員考試行測(cè)試題(A 類(lèi))
- 二零二五年度二手挖掘機(jī)轉(zhuǎn)讓與長(zhǎng)期維護(hù)服務(wù)協(xié)議3篇
- 二零二五年度SSL協(xié)議安全審計(jì)與合規(guī)檢查合同3篇
- 2025年度鮮花電商物流配送與銷(xiāo)售合作協(xié)議3篇
- 2024年供應(yīng)鏈安全培訓(xùn):深入剖析與應(yīng)用
- 飛鼠養(yǎng)殖技術(shù)指導(dǎo)
- 壞死性筋膜炎
- 整式的加減單元測(cè)試題6套
- 股權(quán)架構(gòu)完整
- 山東省泰安市2022年初中學(xué)業(yè)水平考試生物試題
- 注塑部質(zhì)量控制標(biāo)準(zhǔn)全套
- 銀行網(wǎng)點(diǎn)服務(wù)禮儀標(biāo)準(zhǔn)培訓(xùn)課件
- 二年級(jí)下冊(cè)數(shù)學(xué)教案 -《數(shù)一數(shù)(二)》 北師大版
- 晶體三極管資料
- 石群邱關(guān)源電路(第1至7單元)白底課件
評(píng)論
0/150
提交評(píng)論