java筆試--運(yùn)算符_第1頁(yè)
java筆試--運(yùn)算符_第2頁(yè)
java筆試--運(yùn)算符_第3頁(yè)
java筆試--運(yùn)算符_第4頁(yè)
java筆試--運(yùn)算符_第5頁(yè)
已閱讀5頁(yè),還剩24頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論