Java程序員面試分類(lèi)真題7_第1頁(yè)
Java程序員面試分類(lèi)真題7_第2頁(yè)
Java程序員面試分類(lèi)真題7_第3頁(yè)
Java程序員面試分類(lèi)真題7_第4頁(yè)
Java程序員面試分類(lèi)真題7_第5頁(yè)
已閱讀5頁(yè),還剩41頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Java程序員面試分類(lèi)真題7一、單項(xiàng)選擇題1.

以下可以對(duì)對(duì)象加互斥鎖的關(guān)鍵字是______。A.synchronizedB.serializeC.volatileD.static正確答案:(江南博哥)A[解析]對(duì)于選項(xiàng)A,synchronized(同步的)是Java語(yǔ)言的關(guān)鍵字,主要用來(lái)給對(duì)象和方法或者代碼塊加鎖,當(dāng)它鎖定一個(gè)方法或者一個(gè)代碼塊的時(shí)候,同一時(shí)刻最多只有一個(gè)線(xiàn)程執(zhí)行這段代碼。當(dāng)兩個(gè)并發(fā)線(xiàn)程訪(fǎng)問(wèn)同一個(gè)對(duì)象中的這個(gè)加鎖同步代碼塊時(shí),同一時(shí)間只能有一個(gè)線(xiàn)程執(zhí)行。所以,選項(xiàng)A正確。

對(duì)于選項(xiàng)B,serialize是序列化的意思,所謂對(duì)象的序列化指的是把對(duì)象轉(zhuǎn)換為字節(jié)序列的過(guò)程,所謂對(duì)象的反序列化指的是把字節(jié)序列恢復(fù)為對(duì)象的過(guò)程。通常,對(duì)象的序列化主要有以下兩種用途:①把對(duì)象的字節(jié)序列永久地保存到硬盤(pán)上,通常存放在一個(gè)文件中;②在網(wǎng)絡(luò)上傳送對(duì)象的字節(jié)序列。在Java語(yǔ)言中,序列化通過(guò)Serializable接口來(lái)實(shí)現(xiàn)。所以,選項(xiàng)B不正確。

對(duì)于選項(xiàng)C,在由Java語(yǔ)言編寫(xiě)的程序中,有時(shí)候?yàn)榱颂岣叱绦虻倪\(yùn)行效率,編譯器會(huì)做一些優(yōu)化操作,把經(jīng)常被訪(fǎng)問(wèn)的變量緩存起來(lái),程序在讀取這個(gè)變量的時(shí)候有可能會(huì)直接從寄存器中來(lái)讀取這個(gè)值,而不會(huì)去內(nèi)存中讀取。這樣做的一個(gè)好處是提高了程序的運(yùn)行效率,但當(dāng)遇到多線(xiàn)程編程時(shí),變量的值可能被其他線(xiàn)程改變了,而該緩存的值不會(huì)做相應(yīng)的改變,從而造成應(yīng)用程序讀取的值和實(shí)際的變量值不一致。關(guān)鍵字volatile正好能夠解決這一問(wèn)題,被關(guān)鍵字volatile修飾的變量編譯器不會(huì)做優(yōu)化,每次都會(huì)從內(nèi)存中讀取。所以,選項(xiàng)C不正確。

對(duì)于選項(xiàng)D,關(guān)鍵字static主要有以下兩種作用:第一,為某特定數(shù)據(jù)類(lèi)型或?qū)ο蠓峙鋯我坏拇鎯?chǔ)空間,而與創(chuàng)建對(duì)象的個(gè)數(shù)無(wú)關(guān);第二,希望某個(gè)方法或?qū)傩耘c類(lèi)而不是對(duì)象關(guān)聯(lián)在一起,也就是說(shuō),在不創(chuàng)建對(duì)象的情況下就可以通過(guò)類(lèi)來(lái)直接調(diào)用方法或使用類(lèi)的屬性。總之,被static修飾的屬性(方法)是類(lèi)的屬性(方法),不屬于任何對(duì)象。所以,選項(xiàng)D不正確。

2.

JavaTbread中的方法resume()負(fù)責(zé)恢復(fù)哪些線(xiàn)程的執(zhí)行?______A.通過(guò)調(diào)用wait()方法而停止運(yùn)行的線(xiàn)程B.通過(guò)調(diào)用sleep()方法而停止運(yùn)行的線(xiàn)程C.通過(guò)調(diào)用stop()方法而停止運(yùn)行的線(xiàn)程D.通過(guò)調(diào)用suspend()方法而停止運(yùn)行的線(xiàn)程正確答案:D[解析]對(duì)于選項(xiàng)A,wait()方法是一種使線(xiàn)程暫停執(zhí)行的方法,例如,當(dāng)線(xiàn)程交互時(shí),如果線(xiàn)程對(duì)一個(gè)同步對(duì)象發(fā)出了一個(gè)wait()調(diào)用請(qǐng)求,那么該線(xiàn)程會(huì)暫停執(zhí)行,被調(diào)對(duì)象進(jìn)入等待狀態(tài),直到被喚醒(通常使用notify方法喚醒)或等待時(shí)間超時(shí)。所以,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,sleep()方法的作用是使當(dāng)前運(yùn)行的線(xiàn)程休眠指定的時(shí)間。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,可以使用stop()方法來(lái)終止線(xiàn)程的執(zhí)行。當(dāng)使用Tbread.stop()方法來(lái)終止線(xiàn)程時(shí),它會(huì)釋放已經(jīng)鎖定的所有的監(jiān)視資源。如果當(dāng)前任何一個(gè)受這些監(jiān)視資源保護(hù)的對(duì)象處于一個(gè)不一致的狀態(tài),其他的線(xiàn)程將會(huì)看到這個(gè)不一致的狀態(tài),這可能會(huì)導(dǎo)致程序執(zhí)行的不確定性,并且這種問(wèn)題很難被定位。因此,不推薦使用。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,suspend()方法就是將一個(gè)線(xiàn)程掛起(暫停),并且不會(huì)自動(dòng)恢復(fù),必須通過(guò)調(diào)用對(duì)應(yīng)的resume()方法,才能使得線(xiàn)程重新進(jìn)入可執(zhí)行狀態(tài)。所以,選項(xiàng)D正確。

3.

在一個(gè)線(xiàn)程中,sleep(100)方法將使得該線(xiàn)程在______后獲得對(duì)CPU的控制(假設(shè)睡眠過(guò)程中不會(huì)有其他事件喚醒該線(xiàn)程)。A.正好100msB.100ms不到C.≥100msD.不一定正確答案:C[解析]Tbread.sleep(longmillis)和Tbread.sleep(longmillis,intnanos)靜態(tài)方法強(qiáng)制當(dāng)前正在執(zhí)行的線(xiàn)程休眠(即暫停執(zhí)行),當(dāng)線(xiàn)程睡眠時(shí),它睡在某個(gè)地方,在蘇醒之前不會(huì)返回到可運(yùn)行狀態(tài)。當(dāng)睡眠時(shí)間到期,則返回到可運(yùn)行狀態(tài)。所以,sleep()方法指定的時(shí)間為線(xiàn)程不會(huì)運(yùn)行的最短時(shí)間。當(dāng)線(xiàn)程休眠時(shí)間結(jié)束后,會(huì)返回到可運(yùn)行狀態(tài),注意不是運(yùn)行狀態(tài),如果要到運(yùn)行狀態(tài)還需要等待CPU調(diào)度執(zhí)行。因此,sleep()方法不能保證該線(xiàn)程睡眠到期后就開(kāi)始執(zhí)行。所以,選項(xiàng)C正確。

引申:sleep與wait有什么區(qū)別?

sleep()是使線(xiàn)程暫停執(zhí)行一段時(shí)間的方法。wait()也是一種使線(xiàn)程暫停執(zhí)行的方法,例如,當(dāng)線(xiàn)程交互時(shí),如果線(xiàn)程對(duì)一個(gè)同步對(duì)象x發(fā)出一個(gè)wait()調(diào)用請(qǐng)求,那么該線(xiàn)程會(huì)暫停執(zhí)行,被調(diào)對(duì)象進(jìn)入等待狀態(tài),直到被喚醒或等待時(shí)間超時(shí)。

具體而言,sleep與wait的區(qū)別主要表現(xiàn)在以下幾個(gè)方面:

1)原理不同。sleep是Thread類(lèi)的靜態(tài)方法,是線(xiàn)程用來(lái)控制自身流程的,它會(huì)使此線(xiàn)程暫停執(zhí)行指定時(shí)間,而把執(zhí)行機(jī)會(huì)讓給其他線(xiàn)程,等到計(jì)時(shí)時(shí)間到時(shí),此線(xiàn)程會(huì)自動(dòng)蘇醒。例如,當(dāng)線(xiàn)程執(zhí)行報(bào)時(shí)功能時(shí),每一秒鐘打印出一個(gè)時(shí)間,那么此時(shí)就需要在打印方法前面加上一個(gè)sleep方法,以便讓自己每隔一秒執(zhí)行一次,該過(guò)程如同鬧鐘一樣。而wait是Object類(lèi)的方法,用于線(xiàn)程間的通信,這個(gè)方法會(huì)使當(dāng)前擁有該對(duì)象鎖的進(jìn)程等待,直到其他線(xiàn)程調(diào)用notify方法(或notifyAll方法)時(shí)才醒來(lái),不過(guò)開(kāi)發(fā)人員也可以給它指定一個(gè)時(shí)間,自動(dòng)醒來(lái)。與wait配套的方法還有notify和notifyAll。

2)對(duì)鎖的處理機(jī)制不同。由于sleep方法的主要作用是讓線(xiàn)程休眠指定的一段時(shí)間,在時(shí)間到時(shí)自動(dòng)恢復(fù),不涉及線(xiàn)程間的通信,因此,調(diào)用sleep方法并不會(huì)釋放鎖。而wait方法則不同,當(dāng)調(diào)用wait方法后,線(xiàn)程會(huì)釋放掉它所占用的鎖,從而使線(xiàn)程所在對(duì)象中的其他synchronized數(shù)據(jù)可被其他線(xiàn)程使用。舉個(gè)簡(jiǎn)單例子,在小明拿遙控器期間,他可以用自己的sleep方法每隔十分鐘調(diào)一次電視臺(tái),而在他調(diào)臺(tái)休息的十分鐘期問(wèn),遙控器還在他的手上。

3)使用區(qū)域不同。由于wait方法的特殊意義,所以,它必須放在同步控制方法或者同步語(yǔ)句塊中使用,而sleep方法則可以放在任何地方使用。

4)sleep方法必須捕獲異常,而wait、notify以及notifyall不需要捕獲異常。在sleep的過(guò)程中,有可能被其他對(duì)象調(diào)用它的interrupt(),產(chǎn)生InterruptedException異常。

由于sleep不會(huì)釋放“鎖標(biāo)志”,容易導(dǎo)致死鎖問(wèn)題的發(fā)生,所以,一般情況下,不推薦使用sleep方法,而推薦使用wait方法。

4.

下面不是mead類(lèi)的方法是______。A.run!()B.start()C.exit()D.stop()正確答案:C[解析]在Java語(yǔ)言中,Tharead類(lèi)位于java.lang命名空間下。Thread類(lèi)主要用于創(chuàng)建并控制線(xiàn)程、設(shè)置線(xiàn)程優(yōu)先級(jí)并獲取其狀態(tài)。

本題中,對(duì)于選項(xiàng)A,要實(shí)現(xiàn)多線(xiàn)程,在繼承了Thread類(lèi)后必須實(shí)現(xiàn)run()方法,也就是說(shuō),線(xiàn)程的核心邏輯都存在于run()方法中。這個(gè)方法被start()方法調(diào)用來(lái)實(shí)現(xiàn)多線(xiàn)程的功能,如果直接調(diào)用run()方法,那么就與調(diào)用普通的方法類(lèi)似。所以,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,Tbread類(lèi)提供了一個(gè)start()方法,該方法的功能是讓這個(gè)線(xiàn)程開(kāi)始執(zhí)行,當(dāng)開(kāi)始執(zhí)行后,JVM將會(huì)調(diào)用這個(gè)線(xiàn)程的run()方法來(lái)執(zhí)行這個(gè)線(xiàn)程的任務(wù)。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,Tbread類(lèi)沒(méi)有exit()這個(gè)方法。所以,選項(xiàng)C正確。

對(duì)于選項(xiàng)D,Thread類(lèi)的stop()方法是用來(lái)停止一個(gè)線(xiàn)程的,但是由于這個(gè)方法不是線(xiàn)程安全的,因此,通常不推薦使用。所以,選項(xiàng)D錯(cuò)誤。

5.

有如下代碼:

publicstaticvoidmain(Stringargs[])

{

Threadt=DewThread()

{

publicvoidrun()

{

world();

}

};

t.run();

System.out.print("hello");

}

staticvoidworld()

{

System.out.print("world");

}

上面程序的運(yùn)行結(jié)果是______。A.helloworldB.worldhelloC.A和B都有可能D.都不輸出正確答案:B[解析]Thread類(lèi)提供了一個(gè)start()方法,這個(gè)方法的功能是讓這個(gè)線(xiàn)程開(kāi)始執(zhí)行,當(dāng)開(kāi)始執(zhí)行后,JVM將會(huì)調(diào)用這個(gè)線(xiàn)程的run()方法來(lái)執(zhí)行這個(gè)線(xiàn)程的任務(wù)。如果直接調(diào)用run()方法就與調(diào)用普通的方法類(lèi)似。

對(duì)于本題而言,首先調(diào)用t.run()方法,輸出“world”,等調(diào)用結(jié)束后才會(huì)執(zhí)行System.out.print("hello")語(yǔ)句,輸出“hello”。所以,選項(xiàng)B正確。

如果把t.run()改成t.start(),在調(diào)用t.start()方法后不需要等這個(gè)線(xiàn)程結(jié)束,這個(gè)方法就會(huì)立即返回,然后執(zhí)行語(yǔ)句System.out.print("Hllo"),在這種情況下,這兩個(gè)輸出語(yǔ)句的執(zhí)行順序是無(wú)法保證的,任何一個(gè)語(yǔ)句都有可能先執(zhí)行,因此,答案就是選項(xiàng)C。

6.

有如下代碼:

publicclassTestextendsThread

{

publicstaticvoidmain(Stringargv[])

{

Testb=newTest();

b.run();

}

publicvoidstart()

{

for(inti=0;i<10;i++)

{

System.out.println("Valueofi="+i);

}

}

}

當(dāng)編譯并運(yùn)行上面程序時(shí),輸出結(jié)果是______。A.編譯錯(cuò)誤,指明run方法沒(méi)有定義B.運(yùn)行錯(cuò)誤,指明run方法沒(méi)有定義C.編譯通過(guò)并輸出0到9D.編譯通過(guò)但無(wú)輸出正確答案:D[解析]在Java語(yǔ)言中,可以采用以下兩種方法來(lái)創(chuàng)建線(xiàn)程:繼承Thread類(lèi)與實(shí)現(xiàn)Runnable接口。其中,在使用Runnable接口時(shí),需要建立一個(gè)Thread實(shí)例。所以,無(wú)論是通過(guò)Thread類(lèi)創(chuàng)建線(xiàn)程還是通過(guò)Runnable接口創(chuàng)建線(xiàn)程,都必須建立Thread類(lèi)或它的子類(lèi)的實(shí)例。

Thread類(lèi)提供了一個(gè)start()方法,該方法的功能是讓這個(gè)線(xiàn)程開(kāi)始執(zhí)行,當(dāng)這個(gè)線(xiàn)程開(kāi)始執(zhí)行后,JVM將會(huì)調(diào)用這個(gè)線(xiàn)程的run()方法來(lái)執(zhí)行這個(gè)線(xiàn)程的任務(wù)。在實(shí)現(xiàn)多線(xiàn)程時(shí),在繼承了Thread類(lèi)后必須實(shí)現(xiàn)run()方法,也就是說(shuō),線(xiàn)程的核心邏輯都存在于run()方法中,這個(gè)方法被start()方法調(diào)用來(lái)實(shí)現(xiàn)多線(xiàn)程的功能,如果直接調(diào)用run()方法,就與調(diào)用普通的方法類(lèi)似。

對(duì)于本題而言,Test類(lèi)繼承了Thread類(lèi),但是沒(méi)有重寫(xiě)Thread類(lèi)的run()方法,因此,b.run()實(shí)際上調(diào)用的是Tbread類(lèi)的run()方法,而Thread類(lèi)的run()方法的方法體為空,故這個(gè)程序能編譯通過(guò),但是沒(méi)有輸出結(jié)果。所以,選項(xiàng)D正確。

7.

以下可以啟動(dòng)一個(gè)線(xiàn)程的方法是______。A.start()B.ran()C.begin()D.notify()正確答案:A[解析]Thread類(lèi)提供了一個(gè)start方法,這個(gè)方法的功能是讓這個(gè)線(xiàn)程開(kāi)始執(zhí)行,開(kāi)始執(zhí)行后,JVM將會(huì)調(diào)用這個(gè)線(xiàn)程的run方法來(lái)執(zhí)行這個(gè)線(xiàn)程的任務(wù)。在實(shí)現(xiàn)多線(xiàn)程的時(shí)候,在繼承了Thread方法后必須實(shí)現(xiàn)run方法,也就是說(shuō),線(xiàn)程的核心邏輯都存在于run方法中。這個(gè)方法被start方法調(diào)用來(lái)實(shí)現(xiàn)多線(xiàn)程的功能,如果直接調(diào)用run方法就與調(diào)用普通的方法類(lèi)似。所以,選項(xiàng)A正確,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,在Java語(yǔ)言中,線(xiàn)程是沒(méi)有begin方法的。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,notify方法是用來(lái)喚醒一個(gè)線(xiàn)程的,而不是啟動(dòng)一個(gè)線(xiàn)程。所以,選項(xiàng)D錯(cuò)誤。

8.

對(duì)于Java語(yǔ)言中的Daemon線(xiàn)程,setDaemon設(shè)置必須要______。A.在start之后B.在start之前C.前后都可以D.前后都不可以正確答案:B[解析]Java語(yǔ)言提供了兩種線(xiàn)程:守護(hù)線(xiàn)程(DaemonThread)與用戶(hù)線(xiàn)程。守護(hù)線(xiàn)程又稱(chēng)為“服務(wù)進(jìn)程”“精靈線(xiàn)程”或“后臺(tái)線(xiàn)程”,是指當(dāng)程序運(yùn)行的時(shí)候,在后臺(tái)提供一種通用服務(wù)的線(xiàn)程,這種線(xiàn)程并不屬于程序中不可或缺的部分。通俗點(diǎn)講,任何一個(gè)守護(hù)線(xiàn)程都是整個(gè)JVM中所有非守護(hù)線(xiàn)程的保姆。

用戶(hù)線(xiàn)程和守護(hù)線(xiàn)程幾乎一樣,唯一的不同之處就在于:如果用戶(hù)線(xiàn)程已經(jīng)全部退出運(yùn)行,只剩下守護(hù)線(xiàn)程存在,JVM也就退出了。因?yàn)楫?dāng)所有的非守護(hù)線(xiàn)程結(jié)束時(shí),沒(méi)有了被守護(hù)者,守護(hù)線(xiàn)程也就沒(méi)有工作可做,也就沒(méi)有繼續(xù)運(yùn)行程序的必要了,程序也就終止,同時(shí)會(huì)殺死所有守護(hù)線(xiàn)程。也就是說(shuō),只要有任何非守護(hù)線(xiàn)程還在運(yùn)行,程序就不會(huì)終止。

在Java語(yǔ)言中,守護(hù)線(xiàn)程一般具有較低的優(yōu)先級(jí),它并非只由JVM內(nèi)部提供,用戶(hù)在編寫(xiě)程序時(shí)也可以自己設(shè)置守護(hù)線(xiàn)程。例如,將一個(gè)用戶(hù)線(xiàn)程設(shè)置為守護(hù)線(xiàn)程的方法就是在調(diào)用start啟動(dòng)線(xiàn)程之前調(diào)用對(duì)象的setDaemon(true)方法,如果將以上參數(shù)設(shè)置為false,則表示的是用戶(hù)進(jìn)程模式。需要注意的是,當(dāng)在一個(gè)守護(hù)線(xiàn)程中產(chǎn)生了其他線(xiàn)程,那么這些新產(chǎn)生的線(xiàn)程默認(rèn)還是守護(hù)線(xiàn)程,用戶(hù)線(xiàn)程也是如此。所以,選項(xiàng)B正確。

9.

當(dāng)線(xiàn)程1使用某個(gè)對(duì)象,而此對(duì)象又需要線(xiàn)程2修改后才能符合線(xiàn)程1的需要,這時(shí)線(xiàn)程1就要等待線(xiàn)程2完成修改工作,這種現(xiàn)象稱(chēng)為_(kāi)_____。A.線(xiàn)程的同步B.線(xiàn)程的調(diào)度C.線(xiàn)程的就緒D.線(xiàn)程的互斥正確答案:A[解析]對(duì)于選項(xiàng)A,同步就是協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行。例如你說(shuō)完,我再說(shuō)。該定義正好與題目描述一致。所以,選項(xiàng)A正確。

對(duì)于選項(xiàng)B,假設(shè)計(jì)算機(jī)的CPU在任意時(shí)刻都只能執(zhí)行一條機(jī)器指令,線(xiàn)程只有獲得CPU的使用權(quán)才能執(zhí)行對(duì)應(yīng)的操作,多線(xiàn)程的并發(fā)運(yùn)行原理為:各個(gè)線(xiàn)程輪流獲得CPU的使用權(quán),來(lái)執(zhí)行對(duì)應(yīng)的操作。線(xiàn)程調(diào)度是指按照特定機(jī)制為多個(gè)線(xiàn)程分配CPU的使用權(quán)。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,線(xiàn)程有多個(gè)狀態(tài),就緒是指這個(gè)線(xiàn)程已經(jīng)有了除CPU外所有的資源,在等待獲取CPU,一旦獲取到CPU的控制權(quán)就可以立即執(zhí)行。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,線(xiàn)程互斥是指某一資源同時(shí)只允許一個(gè)訪(fǎng)問(wèn)者對(duì)其進(jìn)行訪(fǎng)問(wèn),具有唯一性和排它性。但互斥無(wú)法限制訪(fǎng)問(wèn)者對(duì)資源的訪(fǎng)問(wèn)順序,即訪(fǎng)問(wèn)是無(wú)序的。所以,選項(xiàng)D錯(cuò)誤。

10.

有如下代碼:

publicclassXextendsThreadimplementsRunable

{

publicvoidrun()

{

System.out.println("thisisrun()");

}

publicstaticvoidmain(Stringargs[])

{

Threadt=newThread(newX());

t.start();

}

}

程序的運(yùn)行結(jié)果為_(kāi)_____。A.第一行會(huì)產(chǎn)生編譯錯(cuò)誤B.第六行會(huì)產(chǎn)生編譯錯(cuò)誤C.第六行會(huì)產(chǎn)生運(yùn)行錯(cuò)誤D.程序會(huì)運(yùn)行和啟動(dòng)正確答案:D

11.

可以對(duì)對(duì)象加互斥鎖的關(guān)鍵字是______。A.transientB.synchronizedC.serializeD.static正確答案:B

12.

下列可以終止當(dāng)前線(xiàn)程的運(yùn)行的是______。A.當(dāng)拋出一個(gè)異常時(shí)B.當(dāng)該線(xiàn)程調(diào)用sleep()方法時(shí)C.當(dāng)創(chuàng)建一個(gè)新線(xiàn)程時(shí)D.當(dāng)一個(gè)優(yōu)先級(jí)高的線(xiàn)程進(jìn)入就緒狀態(tài)時(shí)正確答案:A

13.

GC線(xiàn)程______守護(hù)線(xiàn)程。A.是B.不是C.不確定正確答案:A[解析]Java語(yǔ)言提供了兩種線(xiàn)程:守護(hù)線(xiàn)程與用戶(hù)線(xiàn)程。守護(hù)線(xiàn)程又被稱(chēng)為“服務(wù)進(jìn)程”“精靈線(xiàn)程”或“后臺(tái)線(xiàn)程”,是指當(dāng)程序運(yùn)行時(shí),在后臺(tái)提供一種通用服務(wù)的線(xiàn)程,這種線(xiàn)程并不屬于程序中不可或缺的部分。通俗點(diǎn)講,任何一個(gè)守護(hù)線(xiàn)程都是整個(gè)JVM中所有非守護(hù)線(xiàn)程的保姆。

用戶(hù)線(xiàn)程和守護(hù)線(xiàn)程幾乎一樣,唯一的不同之處就在于如果用戶(hù)線(xiàn)程已經(jīng)全部退出運(yùn)行,只剩下守護(hù)線(xiàn)程存在,Java虛擬機(jī)也就退出了。因?yàn)楫?dāng)所有的非守護(hù)線(xiàn)程結(jié)束時(shí),沒(méi)有了被守護(hù)者,守護(hù)線(xiàn)程也就沒(méi)有工作可做,也就沒(méi)有繼續(xù)運(yùn)行程序的必要了,程序也就終止,同時(shí)會(huì)殺死所有守護(hù)線(xiàn)程。也就是說(shuō),只要有任何非守護(hù)線(xiàn)程還在運(yùn)行,程序就不會(huì)終止。

在Java語(yǔ)言中,守護(hù)線(xiàn)程一般具有較低的優(yōu)先級(jí),它并非只由JVM內(nèi)部提供,用戶(hù)在編寫(xiě)程序時(shí),也可以自己設(shè)置守護(hù)線(xiàn)程。例如,將一個(gè)用戶(hù)線(xiàn)程設(shè)置為守護(hù)線(xiàn)程的方法就是在調(diào)用start方法啟動(dòng)線(xiàn)程之前調(diào)用對(duì)象的setDaemon(true)方法,如果將以上參數(shù)設(shè)置為false,則表示的是用戶(hù)進(jìn)程模式。需要注意的是,當(dāng)在一個(gè)守護(hù)線(xiàn)程中產(chǎn)生了其他線(xiàn)程,那么這些新產(chǎn)生的線(xiàn)程默認(rèn)還是守護(hù)線(xiàn)程,用戶(hù)線(xiàn)程也是如此。

守護(hù)線(xiàn)程的一個(gè)典型的例子就是垃圾回收器。只要JVM啟動(dòng),它就始終在運(yùn)行,實(shí)時(shí)監(jiān)控和管理系統(tǒng)中可以被回收的資源。

所以,選項(xiàng)A正確。

14.

事務(wù)隔離級(jí)別是由______實(shí)現(xiàn)的。A.HibernateB.Java應(yīng)用程序C.數(shù)據(jù)庫(kù)系統(tǒng)D.JDBC驅(qū)動(dòng)程序正確答案:C[解析]對(duì)于選項(xiàng)A,Hibemate是一個(gè)開(kāi)放源代碼的對(duì)象關(guān)系映射框架,它對(duì)JDBC進(jìn)行了非常輕量級(jí)的對(duì)象封裝,使得Java程序員可以隨心所欲地使用對(duì)象編程思維來(lái)操縱數(shù)據(jù)庫(kù)。所以,選項(xiàng)A不正確。

對(duì)于選項(xiàng)B,Java應(yīng)用程序可以通過(guò)JDBC或Hiberhate對(duì)數(shù)據(jù)庫(kù)系統(tǒng)進(jìn)行訪(fǎng)問(wèn)。雖然JDBC和Hibernate都提供了事務(wù)控制的接口,但這些接口只是把事務(wù)控制相關(guān)的命令發(fā)送給數(shù)據(jù)庫(kù)系統(tǒng),由數(shù)據(jù)庫(kù)系統(tǒng)來(lái)控制事務(wù)的隔離級(jí)別。所以,選項(xiàng)B不正確。

對(duì)于選項(xiàng)C,數(shù)據(jù)庫(kù)系統(tǒng)是為適應(yīng)數(shù)據(jù)處理的需要而發(fā)展起來(lái)的一種較為理想的數(shù)據(jù)處理系統(tǒng),也是一個(gè)為實(shí)際可運(yùn)行的存儲(chǔ)、維護(hù)和應(yīng)用系統(tǒng)提供數(shù)據(jù)的軟件系統(tǒng),是存儲(chǔ)介質(zhì)、處理對(duì)象和管理系統(tǒng)的集合體。在數(shù)據(jù)庫(kù)操作中,為了保證在并發(fā)情況下數(shù)據(jù)讀寫(xiě)的正確性,提出了事務(wù)隔離級(jí)別。在標(biāo)準(zhǔn)SQL規(guī)范中,定義了4個(gè)事務(wù)隔離級(jí)別,分別為未授權(quán)讀取,也稱(chēng)為讀未提交(ReadUncommitted);授權(quán)讀取,也稱(chēng)為讀提交(ReadCommitted);可重復(fù)讀取(RepeatableRead);序列化(Seiializable)。所以,事務(wù)隔離級(jí)別是由數(shù)據(jù)庫(kù)系統(tǒng)實(shí)現(xiàn)的。所以,選項(xiàng)C正確。

對(duì)于選項(xiàng)D,JDBC驅(qū)動(dòng)程序是一種用于執(zhí)行SQL語(yǔ)句的JavaAPI,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪(fǎng)問(wèn)。所以,選項(xiàng)D不正確。

15.

下列選項(xiàng)中,提供了Java存取數(shù)據(jù)庫(kù)能力的包是______。A.java.sqlB.java.swingC.java.ioD.java.awt正確答案:A[解析]包(package)是Java語(yǔ)言提供的一種區(qū)別類(lèi)的命名空間的機(jī)制,它是類(lèi)的組織方式,是一組相關(guān)類(lèi)和接口的集合,提供了訪(fǎng)問(wèn)權(quán)限和命名的管理機(jī)制。

在Java語(yǔ)言中,包的作用主要體現(xiàn)在以下三個(gè)方面:

1)方便查找與使用。將功能相近的類(lèi)放在同一個(gè)包中,可以方便查找與使用。

2)避免命名沖突。由于在不同包中可以存在同名類(lèi),所以,使用包的好處是在一定程度上可以避免命名沖突。

3)訪(fǎng)問(wèn)權(quán)限設(shè)定。某次訪(fǎng)問(wèn)權(quán)限是以包為單位的。

本題中,對(duì)于選項(xiàng)A,java.sql包中主要包含一些訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)相關(guān)的接口。所以,選項(xiàng)A正確。

對(duì)于選項(xiàng)B,java.swing是一個(gè)用于開(kāi)發(fā)Java應(yīng)用程序用戶(hù)界面的開(kāi)發(fā)工具包。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,java.io提供了流處理的相關(guān)接口。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,java.awt包含用于創(chuàng)建用戶(hù)界面和繪制圖形圖像的所有類(lèi)。所以,選項(xiàng)D錯(cuò)誤。

16.

在JDBC中,用于表示數(shù)據(jù)庫(kù)連接的對(duì)象是______。A.StatementB.ConnectionC.PreparedStatementD.DriverManager正確答案:B[解析]JDBC(JavaDataBaseConnectivity,Java數(shù)據(jù)庫(kù)連接)用于在Java程序中實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作功能,它提供了執(zhí)行SQL語(yǔ)句、訪(fǎng)問(wèn)各種數(shù)據(jù)庫(kù)的方法,并為各種不同的數(shù)據(jù)庫(kù)提供統(tǒng)一的操作接口,java.sql包中包含了JDBC操作數(shù)據(jù)庫(kù)的所有類(lèi)。通過(guò)JDBC訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)一般有如下幾個(gè)步驟:

1)加載JDBC驅(qū)動(dòng)器。將數(shù)據(jù)庫(kù)的JDBC驅(qū)動(dòng)加載到classpath中,在基于JavaEE的Web應(yīng)用開(kāi)發(fā)過(guò)程中,通常要把目標(biāo)數(shù)據(jù)庫(kù)產(chǎn)品的JDBC驅(qū)動(dòng)復(fù)制到WEB-INF/lib下。

2)加載JDBC驅(qū)動(dòng),并將其注冊(cè)到DriverManager中。一般使用反射Class.forName(StringdriveNamel。

3)建立數(shù)據(jù)庫(kù)連接,取得Connection對(duì)象。一般通過(guò)DriverManager.getConnection(url,username,passwd)方式實(shí)現(xiàn),其中,url表示連接數(shù)據(jù)庫(kù)的字符串,username表示連接數(shù)據(jù)庫(kù)的用戶(hù)名,passwd表示連接數(shù)據(jù)庫(kù)的密碼。

4)建立Statement對(duì)象或者PreparedStatement對(duì)象。

5)通過(guò)Statement或PreparedStatement對(duì)象執(zhí)行SQL語(yǔ)句。

6)訪(fǎng)問(wèn)結(jié)果集ResultSet對(duì)象。

7)依次將ResultSet、Statement、PreparedStatement、Connection等對(duì)象關(guān)閉,釋放掉所占用的資源。

通過(guò)上述分析可知,選項(xiàng)B正確。

17.

在Java語(yǔ)言中,用于調(diào)用存儲(chǔ)過(guò)程的對(duì)象是______。A.DriverManagerB.ResultSetC.CallableStatemetD.PreparedStatement正確答案:C[解析]存儲(chǔ)過(guò)程(StoredProcedure)是在大型數(shù)據(jù)庫(kù)系統(tǒng)中,一組為了完成特定功能的SQL語(yǔ)句集,存儲(chǔ)在數(shù)據(jù)庫(kù)中經(jīng)過(guò)第一次編譯后再次調(diào)用不需要再次編譯,用戶(hù)通過(guò)指定存儲(chǔ)過(guò)程的名字并給出參數(shù)(如果該存儲(chǔ)過(guò)程帶有參數(shù))來(lái)執(zhí)行它。存儲(chǔ)過(guò)程是數(shù)據(jù)庫(kù)中的一個(gè)重要對(duì)象,任何一個(gè)設(shè)計(jì)良好的數(shù)據(jù)庫(kù)應(yīng)用程序都應(yīng)該用到存儲(chǔ)過(guò)程。

本題中,對(duì)于選項(xiàng)A,DriverManager是JDBC的管理層,它作用于用戶(hù)和驅(qū)動(dòng)程序之間,管理一組JDBC驅(qū)動(dòng)程序的基本服務(wù),提供用來(lái)建立數(shù)據(jù)庫(kù)連接的一系列方法。除此以外,DriverManager還處理諸如驅(qū)動(dòng)程序登錄時(shí)間限制以及登錄與跟蹤消息的顯示等事務(wù)。因此,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,ResultSet表示查詢(xún)的結(jié)果集,通常通過(guò)執(zhí)行查詢(xún)數(shù)據(jù)庫(kù)的語(yǔ)句生成。ResultSet對(duì)象具有指向其當(dāng)前數(shù)據(jù)行的光標(biāo)。最初,光標(biāo)被置于第一行之前,next方法將光標(biāo)移動(dòng)到下一行,因?yàn)樵摲椒ㄔ赗esultSet對(duì)象沒(méi)有下一行時(shí)返回false,所以,可以在while循環(huán)中使用它來(lái)迭代結(jié)果集。因此,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,CallableStatement提供了用來(lái)調(diào)用數(shù)據(jù)庫(kù)中存儲(chǔ)過(guò)程的接口,如果有輸出參數(shù)要注冊(cè),說(shuō)明是輸出參數(shù)。因此,選項(xiàng)C正確。

對(duì)于選項(xiàng)D,PreparedStatement表示預(yù)編譯的SQL語(yǔ)句的對(duì)象,用于執(zhí)行帶參數(shù)的預(yù)編譯SQL語(yǔ)句。因此,選項(xiàng)D錯(cuò)誤。

18.

下面不是標(biāo)準(zhǔn)的Statement類(lèi)的是______。A.StatementB.CallableStatementC.PreparedStatementD.BatchedStatement正確答案:D[解析]本題中,對(duì)于選項(xiàng)A,Statement是Java語(yǔ)言執(zhí)行數(shù)據(jù)庫(kù)操作的一個(gè)重要方法,用于在已經(jīng)建立數(shù)據(jù)庫(kù)連接的基礎(chǔ)上,向數(shù)據(jù)庫(kù)發(fā)送要執(zhí)行的SQL語(yǔ)句,并返回它所生成結(jié)果的對(duì)象,每次執(zhí)行SQL語(yǔ)句時(shí),數(shù)據(jù)庫(kù)都要編譯該SQL語(yǔ)句。以下是一個(gè)最簡(jiǎn)單的SQL語(yǔ)句:

Statementstmt=conn.getStatement();

stmt.executeUpdate("insertintoclientvalues('aa','aaaa')");

所以,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,CallableStatement提供了用來(lái)調(diào)用數(shù)據(jù)庫(kù)中存儲(chǔ)過(guò)程的接口。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,PreparedStatement表示預(yù)編譯的SQL語(yǔ)句的對(duì)象,用于執(zhí)行帶參數(shù)的預(yù)編譯SQL語(yǔ)句。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,不存在BatchedStatement方法。所以,選項(xiàng)D正確。

19.

以下獲取ResutlSet對(duì)象rst的第一行數(shù)據(jù)的方法中,正確的是______。A.rst.hashNext();B.rst.next();C.rst.first();D.rst.nextRow();正確答案:B[解析]ResultSet(結(jié)果集)是數(shù)據(jù)中查詢(xún)結(jié)果返回的一種對(duì)象,通常通過(guò)執(zhí)行查詢(xún)數(shù)據(jù)庫(kù)的語(yǔ)句生成。ResultSet對(duì)象不僅具有存儲(chǔ)功能,還具有操縱數(shù)據(jù)的功能。

ResultSet對(duì)象具有指向其當(dāng)前數(shù)據(jù)行的指針,它包含了符合SQL語(yǔ)句查詢(xún)結(jié)果的所有行,提供了一套get方法(訪(fǎng)問(wèn)當(dāng)前行的不同列)用于對(duì)這些行中數(shù)據(jù)進(jìn)行訪(fǎng)問(wèn)。ResultSet的next方法用于移動(dòng)到ResultSet中的下一行,使下一行成為當(dāng)前行。因此,對(duì)于剛獲取到的ResultSet對(duì)象,第一次調(diào)用next方法就會(huì)得到第一行的數(shù)據(jù)。所以,選項(xiàng)B正確。

所以,本題的答案為B。

20.

為了讓瀏覽器以UTF-8編碼顯示JSP頁(yè)面,下列JSP代碼正確的是______。A.<%pagecontentType=B.<metahttp-equiv=C.把所有的輸出內(nèi)容重新編碼:newSTRing(content.getBytes())D.response.setContentType()正確答案:D[解析]選項(xiàng)A設(shè)置的是服務(wù)器端編碼,選項(xiàng)B設(shè)置的是客戶(hù)端編碼,選項(xiàng)C設(shè)置的是某個(gè)字符串的編碼。只有選項(xiàng)D滿(mǎn)足題意。

21.

Servlet處理請(qǐng)求的方式為_(kāi)_____。A.以程序的方式B.以進(jìn)程的方式C.以線(xiàn)程的方式D.以響應(yīng)的方式正確答案:C[解析]SeiMet是采用Java語(yǔ)言編寫(xiě)的服務(wù)器端程序,運(yùn)行于Web服務(wù)器的Servlet容器中,其主要功能是提供請(qǐng)求/響應(yīng)的Web服務(wù)模式,可以生成動(dòng)態(tài)的Web內(nèi)容,工作原理如圖所示。

Servlet工作原理

Servlet處理客戶(hù)端請(qǐng)求通常有如下幾個(gè)步驟:

1)用戶(hù)通過(guò)單擊一個(gè)鏈接來(lái)向Servlet發(fā)起請(qǐng)求。

2)Web服務(wù)器接收到該請(qǐng)求后,會(huì)把該請(qǐng)求提交給相應(yīng)的容器來(lái)處理,當(dāng)容器發(fā)現(xiàn)這是對(duì)Servlet發(fā)起的請(qǐng)求后,容器此時(shí)會(huì)創(chuàng)建兩個(gè)對(duì)象:HttpServletResponse和HttpServletRequest。

3)容器可以根據(jù)請(qǐng)求消息中的URL消息找到對(duì)應(yīng)的Servlet,然后針對(duì)該請(qǐng)求創(chuàng)建一個(gè)單獨(dú)的線(xiàn)程,同時(shí)把第2)步中創(chuàng)建的兩個(gè)對(duì)象以參數(shù)的形式傳遞到新創(chuàng)建的線(xiàn)程中。

4)容器調(diào)用Servlel的service()方法來(lái)完成對(duì)用戶(hù)請(qǐng)求的響應(yīng),service()方法會(huì)調(diào)用doPost()方法或doGet()方法來(lái)完成具體的響應(yīng)任務(wù),同時(shí)把生成的動(dòng)態(tài)頁(yè)面返回給容器。

5)容器把響應(yīng)消息組裝成HTTP格式返回給客戶(hù)端。此時(shí),這個(gè)線(xiàn)程運(yùn)行結(jié)束,同時(shí)刪除第2)步創(chuàng)建的兩個(gè)對(duì)象.HttpServletResponse和HttpServletRequest。

容器會(huì)針對(duì)每次請(qǐng)求創(chuàng)建一個(gè)新的線(xiàn)程進(jìn)行處理,同時(shí),會(huì)針對(duì)每次請(qǐng)求創(chuàng)建HttpServletResponse和HttpServletRequest兩個(gè)對(duì)象,處理完成后,線(xiàn)程也就退出了。所以,選項(xiàng)C正確。

22.

按照MVC設(shè)計(jì)模式,JSP用于實(shí)現(xiàn)______。A.Controller(控制器)B.View(視圖)C.Model(模型)D.Database(數(shù)據(jù)庫(kù))正確答案:B[解析]使用JSP與Servlet實(shí)現(xiàn)的MVC模型如圖所示。

MVC模型

在這個(gè)MVC模型中,視圖模塊采用JSP來(lái)實(shí)現(xiàn),主要負(fù)責(zé)數(shù)據(jù)的展現(xiàn),視圖可以從控制器上獲取模型的狀態(tài),當(dāng)然不是直接從控制器上獲取到的,而是控制器把模型的數(shù)據(jù)放到一個(gè)視圖可以訪(fǎng)問(wèn)的地方,通過(guò)這種間接的方式來(lái)訪(fǎng)問(wèn)模型的數(shù)據(jù)。

控制器使用Servlet來(lái)實(shí)現(xiàn),客戶(hù)端的所有請(qǐng)求都發(fā)送給Servlet,它接受請(qǐng)求,并根據(jù)請(qǐng)求消息把它們分發(fā)給對(duì)應(yīng)的JSP頁(yè)面來(lái)響應(yīng),同時(shí)根據(jù)需求生成JavaBean實(shí)例供JSP來(lái)使用。

模型采用JavaBean來(lái)實(shí)現(xiàn)的,這個(gè)模塊實(shí)現(xiàn)了實(shí)際的業(yè)務(wù)邏輯。

從以上分析可知,選項(xiàng)B正確。

23.

在JSP葉旨令中,isELIgnored="boolean"的意思是______。A.決定該頁(yè)面是否是一個(gè)錯(cuò)誤處理頁(yè)面B.決定是否實(shí)現(xiàn)setvlet的單線(xiàn)程模式C.決定是否支持EL表示D.沒(méi)有具體的含義正確答案:C[解析]isELIgnored屬性用來(lái)指定該JSP文件是否支持EL(ExpressionLanguage,表達(dá)式語(yǔ)言)表達(dá)式。如果值為true,那么對(duì)于類(lèi)似于${..}這樣的內(nèi)容,直接會(huì)原樣輸出,而不會(huì)進(jìn)行EL表達(dá)式運(yùn)算;如果值為false,那么表示EL表達(dá)式不會(huì)被忽略,該EL表達(dá)式將會(huì)被執(zhí)行。其屬性配置語(yǔ)法格式如下:<%@pageisELIgnored="true|false"%>。所以,選項(xiàng)C正確。

24.

在WEB-INF目錄下,必須存放的文件為_(kāi)_____。A.class文件B.web.xmlC.html文件D.jar文件正確答案:B[解析]WEB-INF是Web應(yīng)用的安全目錄。所謂安全目錄就是客戶(hù)端無(wú)法訪(fǎng)問(wèn),只有服務(wù)端可以訪(fǎng)問(wèn)的目錄。如果想在頁(yè)面中直接訪(fǎng)問(wèn)其中的文件,必須通過(guò)web.xml文件對(duì)要訪(fǎng)問(wèn)的文件進(jìn)行相應(yīng)的映射才行。WEB-INF文件夾下除了web.xml外,還存在一個(gè)classes文件夾,用以放置*.class文件,這些*.class文件是設(shè)計(jì)人員編寫(xiě)的類(lèi)庫(kù),實(shí)現(xiàn)了JSP頁(yè)面前臺(tái)與后臺(tái)服務(wù)的分離,使得網(wǎng)站的維護(hù)非常方便。web.xml文件為網(wǎng)站部署描述XML文件,它對(duì)網(wǎng)站的部署非常重要。因此,web.xml是必不可少的文件。所以,選項(xiàng)B正確。

25.

在JavaScript中,以下驗(yàn)證一個(gè)數(shù)據(jù)是否是數(shù)字的描述中,正確的是______。A.imtI=value若報(bào)錯(cuò)就不是數(shù)字B.如果用Integer.parseInt(yalue)有誤就不是數(shù)字C.沒(méi)有方法驗(yàn)證D.利用isNaN(value)返回的boolean進(jìn)行判斷正確答案:D[解析]對(duì)于選項(xiàng)A,JavaScript是弱類(lèi)型語(yǔ)言(也稱(chēng)為弱類(lèi)型定義語(yǔ)言,與強(qiáng)類(lèi)型定義相反。弱類(lèi)型語(yǔ)言允許將一塊內(nèi)存看作多種類(lèi)型,比如直接將整型變量與字符變量相加。C/C++是靜態(tài)語(yǔ)言,是強(qiáng)類(lèi)型語(yǔ)言;Perl與PHP是動(dòng)態(tài)語(yǔ)言,但也是弱類(lèi)型語(yǔ)言),只有一種類(lèi)型var。所以,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,Integer.parseInt(value)是Java語(yǔ)言中的方法,而不是JavaScript的方法。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,JavaScript中驗(yàn)證一個(gè)數(shù)據(jù)是否是數(shù)字是存在方法的,可以使用isNaN()函數(shù)判斷,也可以使用正則表達(dá)式判斷。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,JavaScript提供了一個(gè)isNaN()函數(shù)用于檢查其參數(shù)是否是非數(shù)字值。所以,選項(xiàng)D正確。

26.

以下不能作JSP的服務(wù)器的是______。A.JBossB.BEAWebLogicC.TomcatD.PWS正確答案:D[解析]Web服務(wù)器指的是提供Web功能的服務(wù)器,主要就是HTTP服務(wù)器,包括圖片的下載等一系列和文本相關(guān)的資源。Web服務(wù)器支持以HTTP協(xié)議的方式來(lái)訪(fǎng)問(wèn),當(dāng)Web服務(wù)器接收到一個(gè)HTTP請(qǐng)求時(shí),它同樣會(huì)以HTTP協(xié)議格式返回一個(gè)響應(yīng),這個(gè)響應(yīng)可以是一個(gè)靜態(tài)的HTML頁(yè)面,也可以是結(jié)果處理的一個(gè)動(dòng)態(tài)的頁(yè)面,還可以是音頻、視頻等信息。為了處理一個(gè)請(qǐng)求,Web服務(wù)器可以做出一個(gè)響應(yīng),并進(jìn)行頁(yè)面跳轉(zhuǎn),或者把動(dòng)態(tài)響應(yīng)的產(chǎn)生委托給一些其他的程序,例如CGl腳本、JSP、Servlet或者一些其他的服務(wù)器端程序。Web服務(wù)器一般都使用了一些特有的機(jī)制(例如容錯(cuò)機(jī)制)來(lái)保證Web服務(wù)器有較好的擴(kuò)展性和不問(wèn)斷地提供服務(wù)。常見(jiàn)的Web服務(wù)器有IIS和Apache。

應(yīng)用服務(wù)器提供訪(fǎng)問(wèn)業(yè)務(wù)邏輯的途徑以供客戶(hù)端應(yīng)用程序使用。具體而言,它通過(guò)HTTP、TCP/IP、IIOP(InternetInter-ORBProtocol,互聯(lián)網(wǎng)內(nèi)部對(duì)象請(qǐng)求代理協(xié)議)或JRMP(JavaRemoteMethodProtocol,Java遠(yuǎn)程方法協(xié)議)等來(lái)提供業(yè)務(wù)邏輯接口。為了系統(tǒng)的可靠性,同樣使用了一些可擴(kuò)展性和容錯(cuò)機(jī)制。除此之外,它還為應(yīng)用的開(kāi)發(fā)提供了許多服務(wù),例如事務(wù)管理、安全管理和對(duì)象生命周期管理等。常見(jiàn)的應(yīng)用服務(wù)器有BEAWebLogicServer、IBMWebSphereApplicationServer、IPlanetApplicationServer、Oracle9iApplicationServer、JBoss和Tomcat等。

Web服務(wù)器一般是通用的,而應(yīng)用服務(wù)器一般是專(zhuān)用的,例如Tomcat只處理Java應(yīng)用程序而不能處理ASPX或PHP。需要注意的是,Web服務(wù)器與應(yīng)用服務(wù)器是并列關(guān)系,二者不存在相互包容關(guān)系。在使用的時(shí)候,如果訪(fǎng)問(wèn)的頁(yè)面只有HTML,用Web服務(wù)器就足夠了,但是如果是JSP,此時(shí)就需要應(yīng)用服務(wù)器,因?yàn)橹挥袘?yīng)用服務(wù)器才能解析JSP里的Java代碼,并將解析結(jié)果以HTML的格式返回給用戶(hù)。

從上面的分析可以看出,選項(xiàng)A、選項(xiàng)B和選項(xiàng)C都可以作為JSP的服務(wù)器。

對(duì)于選項(xiàng)D,PWS(PersonalWebSetwer,個(gè)人Web服務(wù)器)是微軟開(kāi)發(fā)的個(gè)人網(wǎng)站服務(wù)器,主要應(yīng)用于解決個(gè)人信息共享和Web開(kāi)發(fā)。它是一個(gè)桌面形的Web服務(wù)器,使用它可以自動(dòng)創(chuàng)建個(gè)性化主頁(yè),以拖放的方式發(fā)布文檔,在它的幫助下,用戶(hù)可以快速簡(jiǎn)便地進(jìn)行Web站點(diǎn)設(shè)置。由于它只是一個(gè)Web服務(wù)器,因此,它無(wú)法作為JSP的服務(wù)器。所以,選項(xiàng)D正確。

27.

以下不是JSP操作指令的是______。A.setPropertyB.includeC.forwardD.import正確答案:D[解析]JSP總共有6個(gè)操作指令:jsp:include、jsp:useBean、jsp:setProperty、jsp:getProperty、jsp:forward與jsp:plugin。以下將分別對(duì)這幾種指令進(jìn)行介紹。

jsp:include:用來(lái)在頁(yè)面被請(qǐng)求的時(shí)候引入一個(gè)文件。使用示例如下:

<jsp:includepage="test.jsp"flush="true">

<jsp:paramname="name"value="value"/>

</jsp:include>

以上代碼表示在當(dāng)前文件中可以引入test.jsp文件。

jsp:useBean:用來(lái)尋找或者實(shí)例化一個(gè)JavaBean。它使得開(kāi)發(fā)人員既可以發(fā)揮Java組件重用的優(yōu)勢(shì),同時(shí)也避免了損失JSP區(qū)別于Servlet的方便性。使用示例如下:

<jsp:useBean

id="car"scope="session"class="com.Car">

以上代碼表示實(shí)例化了一個(gè)com.Car類(lèi)的實(shí)例。

jsp:setProperty:用來(lái)設(shè)置已經(jīng)實(shí)例化的Bean對(duì)象的屬性。使用示例如下:

<jsp:setPropertyname="car"property="colour"value="red"/>

以上代碼用來(lái)設(shè)置名字為car的實(shí)例的colour屬性為red。

jsp:getProperty:用來(lái)獲取某個(gè)JavaBean的屬性。使用示例如下:

Colom=<jsp:getPropertyname="car"property="colour"></jsp:getProperty>

以上代碼用來(lái)獲取名字為car的實(shí)例的colour屬性。

jsp:foward:用來(lái)把請(qǐng)求轉(zhuǎn)到一個(gè)新頁(yè)面。使用示例如下:

<jsp:forwardpage="/Servlet/login"/>

以上代碼把當(dāng)前頁(yè)面重定向到/Servlet/login來(lái)處理。

jsp:plugin:用于在瀏覽器中播放或顯示一個(gè)對(duì)象。使用這個(gè)動(dòng)作能插入所需的特定瀏覽器的OBJECT或EMBED元素來(lái)指定瀏覽器運(yùn)行一個(gè)JAVAApplet所需的插件。使用示例如下:

<jsp:plugintype="applet"codebase="/ch5"code="Hello.class"height="40"width="320">

以上代碼用來(lái)在瀏覽器中運(yùn)行一個(gè)applet插件。

由此可見(jiàn),選項(xiàng)D中的import不是JSP的操作指令。所以,選項(xiàng)D正確。

28.

348]在配置tomcat虛擬目錄時(shí),需要打開(kāi)的文件是______。A.web.xmlB.index.jspC.server.xmlD.以上都不是正確答案:C[解析]一般情況下,配置虛擬目錄的方法為:

在tomcat\conf下server.xml中找到<Hostname="localhost"appBase="webapps"unpackWARs="true"autoDeploy="true"xmlValidation="false"xmlNamespaceAware="false"></Host>,在其中添加:<Contextpath=""docBase="自定義目錄"reloadable="true"></Context>。因此,選項(xiàng)C正確。

對(duì)于選項(xiàng)A,web.xml可以被看作是JSP的一個(gè)配置文件,其中一個(gè)重要的作用是用來(lái)配置Servlet的路徑。所以,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,index.jsp一般是一個(gè)網(wǎng)站的首頁(yè),不包含與tomcat相關(guān)的配置信息。所以,選項(xiàng)B錯(cuò)誤。

29.

下面不是表單標(biāo)記的是______。A.RADIOB.INPUTC.CHECKBOXD.TR正確答案:D[解析]本題中,對(duì)于選項(xiàng)A,RADIO為單選按鈕控件標(biāo)簽,是表單標(biāo)記。所以,選項(xiàng)A錯(cuò)誤。

對(duì)于選項(xiàng)B,INPUT表示Form表單中的一種輸入對(duì)象,其又隨Type類(lèi)型的不同而分為文本輸入框、密碼輸入框、單選/復(fù)選框及提交/重置按鈕等,是表單標(biāo)記。所以,選項(xiàng)B錯(cuò)誤。

對(duì)于選項(xiàng)C,CHECKBOX為多選復(fù)選框標(biāo)簽,是表單標(biāo)記。所以,選項(xiàng)C錯(cuò)誤。

對(duì)于選項(xiàng)D,TR是表中的行標(biāo)簽,不屬于表單標(biāo)記。所以,選項(xiàng)D正確。

30.

下面不是response對(duì)象的方法的是______。A.addCookie(Cookiecookie)B.setHeader(Stringheademarne,Stringheadervalue)C.getParameter(Stringstr)D.sendError(interrorcode)正確答案:C[解析]response對(duì)象所提供的方法有如下幾類(lèi):

(1)設(shè)定響應(yīng)頭的方法

voidaddCookie(Cookiecookie)

新增cookie

voidaddDateHeader(Stringname,longdate)

新增long類(lèi)型的值到name響應(yīng)頭

voidaddHeader(Stringname,Stringvalue)

新增String類(lèi)型的值到name響應(yīng)頭

voidaddIntHeader(Stringname,intvahe)

新增int類(lèi)型的值到name響應(yīng)頭

voidsetDateHeader(Stringname,longdate)

指定long類(lèi)型的值到name響應(yīng)頭

voidsetHeader(Stringname,Stringvalue)

指定String類(lèi)型的值到name響應(yīng)頭

voidsetIntHeader(Stringname,intvalue)

指定int類(lèi)型的值到name響應(yīng)頭

booleancontainsHeader

判斷指定名字的HTTP文件頭是否已經(jīng)存在,然

后返回真假部爾值

(2)設(shè)定響應(yīng)狀態(tài)碼的方法

voidsendError(intsc)

傳送狀態(tài)碼(StatusCode)

voidsendError(intsc,Stringmsg)

傳送狀態(tài)碼和錯(cuò)誤信息

voidsetStatus(intsc)

設(shè)定狀態(tài)碼

(3)用來(lái)URL重寫(xiě)(Rewriting)的方法

StringencodeRedirectURL(Stringurl)

對(duì)使用sendRedirect()方法的URL予以編碼

(4)設(shè)置重定向

sendRedirect()

設(shè)置重定向頁(yè)面

(5)設(shè)置不同瀏覽器對(duì)應(yīng)的數(shù)據(jù)

setContentType(StringcontentTypestr):使客戶(hù)端瀏覽器,區(qū)分不同種類(lèi)的數(shù)據(jù),并根據(jù)不同的MIME(MultipurposeInternetMailExtensions,多用途互聯(lián)網(wǎng)郵件擴(kuò)展類(lèi)型)調(diào)用瀏覽器內(nèi)不同的程序嵌入模塊來(lái)處理相應(yīng)的數(shù)據(jù)。

所以,選項(xiàng)C正確。

二、多項(xiàng)選擇題1.

以下布局管理器中,使用的是組件的最佳尺寸(PreferredSize)的是______。A.FlowLayoutB.BorderLayoutC.GridLayoutD.CardLayoutE.GridBagLayout正確答案:AE

2.

以下關(guān)于線(xiàn)程的描述中,錯(cuò)誤的是______。A.sleep方法必須寫(xiě)在同步方法或同步塊中B.wait方法執(zhí)行時(shí)會(huì)釋放對(duì)象鎖C.sleep方法執(zhí)行時(shí)會(huì)釋放對(duì)象鎖D.wait方法必須寫(xiě)在同步方法或同步塊中正確答案:AC

3.

Tbread類(lèi)中本身的方法(不包括繼承)有______。A.start()B.sleep(longmi)C.notify()D.wait()正確答案:AB[解析]對(duì)于選項(xiàng)A,start方法是Thread類(lèi)中比較重要的方法,JVM通過(guò)調(diào)用這個(gè)方法啟動(dòng)一個(gè)線(xiàn)程。所以,選項(xiàng)A正確。

對(duì)于選項(xiàng)B,sleep是使線(xiàn)程暫停執(zhí)行一段時(shí)間的方法。所以,選項(xiàng)B正確。

對(duì)于選項(xiàng)C和選項(xiàng)D,wait和notify都是從Object類(lèi)繼承的方法。所以,選項(xiàng)C和選項(xiàng)D錯(cuò)誤。

4.

在Java語(yǔ)言中,如果需要編寫(xiě)一個(gè)多線(xiàn)程程序,可以使用的方法是______。A.實(shí)現(xiàn)Runnable接口B.擴(kuò)展類(lèi)ThreadC.擴(kuò)展類(lèi)RunnableD.實(shí)現(xiàn)接口Thread正確答案:AB[解析]Java多線(xiàn)程實(shí)現(xiàn)常用的有兩種方法:繼承Thread類(lèi)與實(shí)現(xiàn)Runnable接口。所以,選項(xiàng)A與選項(xiàng)B正確。

5.

下列可用于創(chuàng)建一個(gè)可運(yùn)行的類(lèi)的方法有______。A.publicclassXimplementsRunnable{publicvoidrun(){}}B.publicclassXimplementsThread{publicvoidrun(){}}C.publicclassXimplementsRunnable{publicintrun(){}}D.publicclassXimplementsRunnable{protectedvoidrun(){}}E.publicclassXimplementsThread{publicvoidrun(){}}正確答案:AD

6.

下面可以在任何時(shí)候被任何線(xiàn)程調(diào)用的方法有______。A.notify()B.wait()C.notifyall()D.sleep()E.yield()F.synchronized(this)正確答案:DEF

三、論述題1.

實(shí)現(xiàn)多線(xiàn)程的方法有哪幾種?正確答案:Java虛擬機(jī)(JavaVirtualMachine,JVM,是運(yùn)行所有Java程序的抽象計(jì)算機(jī),是Java語(yǔ)言的運(yùn)行環(huán)境)允許應(yīng)用程序并發(fā)地運(yùn)行多個(gè)線(xiàn)程。在Java語(yǔ)言中,多線(xiàn)程的實(shí)現(xiàn)一般有以下三種方法:

1)實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)該接口的run()方法。以下是主要步驟:

①自定義類(lèi)并實(shí)現(xiàn)Runnable接口,實(shí)現(xiàn)run()方法。

②創(chuàng)建Thread對(duì)象,用實(shí)現(xiàn)Runnable接口的對(duì)象作為參數(shù)實(shí)例化該Thread對(duì)象。

③調(diào)用Thread的start()方法。

classMyThreadimplementsRunnable

{//創(chuàng)建線(xiàn)程類(lèi)

publicvoidrun()

{

System.out.println("Threadbody");

}

}

publicclassTest

{

publicstaticvoidmain(String[]args)

{

MyThreadthread=newMyThread();

Threadt=newThread(thread);

t.start();

//開(kāi)啟線(xiàn)程

}

2)繼承Thread類(lèi),重寫(xiě)run方法。Thread本質(zhì)上也是實(shí)現(xiàn)了Runnable接口的一個(gè)實(shí)例,它代表一個(gè)線(xiàn)程的實(shí)例,并且,啟動(dòng)線(xiàn)程的唯一方法就是通過(guò)Thread類(lèi)的start()方法。start()方法是一個(gè)native(本地)方法,它將啟動(dòng)一個(gè)新線(xiàn)程,并執(zhí)行run()方法(Thread中提供的run()方法是一個(gè)空方法)。這種方式通過(guò)自定義類(lèi)直接extendsThread,并重寫(xiě)run()方法,就可以啟動(dòng)新線(xiàn)程并執(zhí)行自己定義的run()方法。需要注意的是,當(dāng)start()方法調(diào)用后并不是立即執(zhí)行多線(xiàn)程代碼,而是使得該線(xiàn)程變?yōu)榭蛇\(yùn)行態(tài)(Runnable),什么時(shí)候運(yùn)行多線(xiàn)程代碼是由操作系統(tǒng)決定的。

下例給出了Thread的使用方法。

classMyThreadextendsThread

{//創(chuàng)建線(xiàn)程類(lèi)

publicvoidrun()

{

System.out.println("Threadbody");

//線(xiàn)程的方法體

}

}

publicclassTest

{

publicstaticvoidmain(String[]args)

{

MyThreadthread=newMyThread();

thread.start();

//開(kāi)啟線(xiàn)程

}

3)實(shí)現(xiàn)Callable接口,重寫(xiě)call()方法。Callable對(duì)象實(shí)際是屬于Executor框架中的功能類(lèi),Callable接口與Runnable接口類(lèi)似,但是提供了比Runnable更強(qiáng)大的功能,主要表現(xiàn)為以下三點(diǎn):

①Callable可以在任務(wù)結(jié)束后提供一個(gè)返回值,Runnable無(wú)法提供這個(gè)功能。

②Callable中的call()方法可以?huà)伋霎惓?,而Runnable的run()方法不能拋出異常。

③運(yùn)行Callable可以拿到一個(gè)Future對(duì)象,F(xiàn)uture對(duì)象表示異步計(jì)算的結(jié)果。它提供了檢查計(jì)算是否完成的方法。由于線(xiàn)程屬于異步計(jì)算模型,所以無(wú)法從其他線(xiàn)程中得到方法的返回值,在這種情況下,就可以使用Future來(lái)監(jiān)視目標(biāo)線(xiàn)程調(diào)用call()方法的情況,當(dāng)調(diào)用Future的get()方法以獲取結(jié)果時(shí),當(dāng)前線(xiàn)程就會(huì)阻塞,直到call()方法結(jié)束返回結(jié)果。

示例代碼如下:

importjava.util.concurrent.*;

publicclassCallableAndFuture

{

//創(chuàng)建線(xiàn)程類(lèi)

publicstaticclassCallableTestimplementsCallable<String>

{

publicStringcall()throwsException

{

return"HelloWorld!";

}

}

publicstaticvoidmain(String[]args)

{

ExecutorServicethreadPool=Executors.newSingleThreadExecutor();

//啟動(dòng)線(xiàn)程

Future<String>future=threadPool.submit(newCallableTest());

try

{

System.out.println("waitingthreadtofinish");

System.out.println(future.get());//等待線(xiàn)程結(jié)束,并獲取返回結(jié)果

}

catch(Exceptione)

{

e.printStackTrace();

}

}

}

上述程序的運(yùn)行結(jié)果為:

waitingthreadtofinish

HelloWorid!

在以上三種方式中,前兩種方式線(xiàn)程執(zhí)行完后都沒(méi)有返回值,只有最后一種是帶返回值的。當(dāng)需要實(shí)現(xiàn)多線(xiàn)程時(shí),一般推薦實(shí)現(xiàn)Runnable接口的方式,原因如下:首先,Thread類(lèi)定義了多種方法可以被派生類(lèi)使用或重寫(xiě),但是只有run方法是必須被重寫(xiě)的,在run方法中實(shí)現(xiàn)這個(gè)線(xiàn)程的主要功能。這當(dāng)然是實(shí)現(xiàn)Runnable接口所需的同樣的方法。而且,很多Java開(kāi)發(fā)人員認(rèn)為,一個(gè)類(lèi)僅在它們需要被加強(qiáng)或修改時(shí)才會(huì)被繼承。因此,如果沒(méi)有必要重寫(xiě)Thread類(lèi)中的其他方法,那么通過(guò)繼承Thread的實(shí)現(xiàn)方式與實(shí)現(xiàn)Runnable接口的效果相同,在這種情況下最好通過(guò)實(shí)現(xiàn)Runnable接口的方式來(lái)創(chuàng)建線(xiàn)程。

2.

多線(xiàn)程同步有幾種實(shí)現(xiàn)方法?正確答案:當(dāng)使用多線(xiàn)程訪(fǎng)問(wèn)同一個(gè)資源時(shí),非常容易出現(xiàn)線(xiàn)程安全的問(wèn)題(例如,當(dāng)多個(gè)線(xiàn)程同時(shí)對(duì)一個(gè)數(shù)據(jù)進(jìn)行修改時(shí),會(huì)導(dǎo)致某些線(xiàn)程對(duì)數(shù)據(jù)的修改丟失)。因此,需要采用同步機(jī)制來(lái)解決這種問(wèn)題。Java主要提供了三種實(shí)現(xiàn)同步機(jī)制的方法:

(1)synchronized關(guān)鍵字

在Java語(yǔ)言中,每個(gè)對(duì)象都有一個(gè)對(duì)象鎖與之相關(guān)聯(lián),該鎖表明對(duì)象在任何時(shí)候只允許被一個(gè)線(xiàn)程所擁有,當(dāng)一個(gè)線(xiàn)程調(diào)用對(duì)象的一段synchronized代碼時(shí),首先需要獲取這個(gè)鎖,然后去執(zhí)行相應(yīng)的代碼,執(zhí)行結(jié)束后,釋放鎖。

synchronized關(guān)鍵字主要有兩種用法(synchronized方法和synchronized塊),此外該關(guān)鍵字還可以作用于靜態(tài)方法、類(lèi)或某個(gè)實(shí)例,但這都對(duì)程序的效率有很大的影響。

1)synchronized方法。在方法的聲明前加入synchronized關(guān)鍵字。例如:

publicsynchronizedvoidmutiThreadAccess();

只要把多個(gè)線(xiàn)程訪(fǎng)問(wèn)的資源的操作放到mutiThreadAccess方法中,就能夠保證這個(gè)方法在同一時(shí)刻只能被一個(gè)線(xiàn)程訪(fǎng)問(wèn),從而保證了多線(xiàn)程訪(fǎng)問(wèn)的安全性。然而,當(dāng)一個(gè)方法的方法體規(guī)模非常大時(shí),把該方法聲明為synchronized會(huì)大大影響程序的執(zhí)行效率。為了提高程序的執(zhí)行效率,Java語(yǔ)言提供了synchronized塊。

2)synchronized塊??梢园讶我獾拇a段聲明為synchronized,也可以指定上鎖的對(duì)象,有非常高的靈活性。用法如下:

synchronized(syncObject){

//訪(fǎng)問(wèn)syncObject的代碼

}

(2)wait與notify

當(dāng)使用synchronized來(lái)修飾某個(gè)共享資源的時(shí)候,如果線(xiàn)程A1在執(zhí)行synchronized代碼,另外一個(gè)線(xiàn)程A2也要同時(shí)執(zhí)行同一對(duì)象的同一synchronized代碼時(shí),線(xiàn)程A2將要等到線(xiàn)程A1執(zhí)行完成后,才能繼續(xù)執(zhí)行。在這種情況下,可以使用wait方法和notify方法。

在synchronized代碼被執(zhí)行期間,線(xiàn)程可以調(diào)用對(duì)象的wait方法,釋放對(duì)象鎖,進(jìn)入等待狀態(tài),并且可以調(diào)用notify方法或notifyAll方法通知正在等待的其他線(xiàn)程,notify方法僅喚醒一個(gè)線(xiàn)程(等待隊(duì)列中的第一個(gè)線(xiàn)程),并允許它去獲得鎖,而notifyAll方法喚醒所有等待這個(gè)對(duì)象的線(xiàn)程,并允許它們?nèi)カ@得鎖(并不是讓所有喚醒線(xiàn)程都獲取到鎖,而是讓它們?nèi)ジ?jìng)爭(zhēng))。

(3)Lock

JDK5新增加了Lock接口以及它的一個(gè)實(shí)現(xiàn)類(lèi)ReentrantLock(重入鎖),Lock也可以用來(lái)實(shí)現(xiàn)多線(xiàn)程的同步,具體而言,它提供了如下的一些方法來(lái)實(shí)現(xiàn)多線(xiàn)程的同步:

1)lock()。以阻塞的方式來(lái)獲取鎖,也就是說(shuō),如果獲取到了鎖,則立即返回,如果其他線(xiàn)程持有鎖,當(dāng)前線(xiàn)程等待,直到獲取鎖后返回。

2)tryLock()。以非阻塞的方式獲取鎖。只是嘗試性地去獲取一下鎖,如果獲取到鎖,則立即返回true,否則,立即返回false。

3)tryLock(longtimeout,TimeUnitunit)。如果獲取了鎖,立即返回true,否則,會(huì)等待參數(shù)給定的時(shí)間單元,在等待的過(guò)程中,如果獲取了鎖,就返回true,如果等待超時(shí),則返回false。

4)lockInterruptibly()。如果獲取了鎖,則立即返回,如果沒(méi)有獲取鎖,則當(dāng)前線(xiàn)程處于休眠狀態(tài),直到獲得鎖,或者當(dāng)前線(xiàn)程被其他線(xiàn)程中斷(會(huì)收到InterruptedException異常)。它與lock()方法最大的區(qū)別在于:如果lock()方法獲取不到鎖,則會(huì)一直處于阻塞狀態(tài),且會(huì)忽略interrupt()方法。如下例所示:

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

publicclassTest{

publicstaticvoidmain(String[]args)throwsInterruptedException{

finalLocklock=newReentrantLock();

lock.lock();

Threadt1=newThread(newRunnable(){

publicvoidrun(){

try{

lock.lockInterruptibly();

//lock.lock();編譯器報(bào)錯(cuò)

}catch(InterruptedExceptione){

System.out.println("interrupted.");

}

}

});

t1.start();

errupt();

Thread.sleep(1);

}

}

程序的運(yùn)行結(jié)果為:

interrupted.

如果把lock.lockInterruptibly()替換為lock.lock(),編譯器將會(huì)提示lock.lock()catch代碼塊無(wú)效,因?yàn)閘ock.lock()不會(huì)拋出異常,由此可見(jiàn),lock()方法會(huì)忽略interrupt()引發(fā)的異常。

3.

在多線(xiàn)程編程的時(shí)候有哪些注意事項(xiàng)?正確答案:多線(xiàn)程編程是一項(xiàng)非常重要的技能。如何能避免死鎖,如何提高多線(xiàn)程并發(fā)情況下的性能是非常重要的,下面列出一些在多線(xiàn)程編程情況下的指導(dǎo)原則:

1)如果能用volatile代替synchronized,盡可能用volatile。因?yàn)楸籹ynchronized修飾的方法或代碼塊在同一時(shí)間只允許一個(gè)線(xiàn)程訪(fǎng)問(wèn),而volatile卻沒(méi)有這個(gè)限制,因此使用synchronized會(huì)降低并發(fā)量。由于volatile無(wú)法保證原子操作,因此在多線(xiàn)程的情況下,只有對(duì)變量的操作為原子操作的情況下才可以使用volatile。

2)盡可能減少synchronized塊內(nèi)的代碼,只把臨界區(qū)的代碼放到synchronized塊中,盡量避免用synchronized來(lái)修飾整個(gè)方法。

3)盡可能給每個(gè)線(xiàn)程都定義一個(gè)線(xiàn)程的名字,不要使用匿名線(xiàn)程,這樣有利于調(diào)試。

4)盡可能用concurrent容器(ConcurrentHashMap)來(lái)代替synchronized容器(Hashtable)。因?yàn)閟ynchronized容器使用synchronized關(guān)鍵字通過(guò)對(duì)整個(gè)容器加鎖來(lái)實(shí)現(xiàn)多線(xiàn)程安全,性能比較低。而ConcurrentHashMap采用了更加細(xì)粒度的鎖,因此可以支持更高的并發(fā)量。

5)使用線(xiàn)程池來(lái)控制多線(xiàn)程的執(zhí)行。

4.

一個(gè)文件中有10000個(gè)數(shù),用Java語(yǔ)言實(shí)現(xiàn)一個(gè)多線(xiàn)程程序,將這10000個(gè)數(shù)輸出到5個(gè)不同文件中(不要求輸出到每個(gè)文件中的數(shù)量相同)。要求啟動(dòng)10個(gè)線(xiàn)程,兩兩一組,分為5組。每組兩個(gè)線(xiàn)程分別將文件中的奇數(shù)和偶數(shù)輸出到該組對(duì)應(yīng)的一個(gè)文件中,需要偶數(shù)線(xiàn)程每打印10個(gè)偶數(shù)以后,就將奇數(shù)線(xiàn)程打印10個(gè)奇數(shù),如此交替進(jìn)行。同時(shí)需要記錄輸出進(jìn)度,每完成1000個(gè)數(shù)就在控制臺(tái)中打印當(dāng)前完成數(shù)量,并在所有線(xiàn)程結(jié)束后,在控制臺(tái)輸出“Done”。正確答案:本題考查的是對(duì)多線(xiàn)程編程的理解。為了便于理解,首先用隨機(jī)函數(shù)隨機(jī)生成10000個(gè)數(shù)放到文件中,以供測(cè)試使用。一次把這10000條記錄讀到內(nèi)存中,平均分配給5組線(xiàn)程并行處理,因此,本題的難點(diǎn)是如何控制打印偶數(shù)的線(xiàn)程和打印奇數(shù)的線(xiàn)程輪流運(yùn)行。

本題通過(guò)Java提供的Condition來(lái)實(shí)現(xiàn)線(xiàn)程的同步。Condition是在Java1.5中才出現(xiàn)的,它用來(lái)替代傳統(tǒng)的Object類(lèi)的wait()、notify()方法,以實(shí)現(xiàn)線(xiàn)程間的協(xié)作,相比使用Object類(lèi)的wait()、nofify()方法,使用Condition的await()、signal()這種方式實(shí)現(xiàn)線(xiàn)程間協(xié)作,更加安全和高效。它主要有如下特點(diǎn):

1)Condition最常用的方法為await()和signal(),其中,await()對(duì)應(yīng)Object類(lèi)的wait()方法,signal()對(duì)應(yīng)Object類(lèi)的notify()方法。

2)Condition依賴(lài)于Lock接口,生成一個(gè)Condition的代碼為lock.newCondition()。

3)調(diào)用Condition的await()和signal()方法必須在lock保護(hù)之內(nèi)。

對(duì)于本題而言,定義兩個(gè)Condition(oddLock和evenLock),首先打印奇數(shù)的線(xiàn)程開(kāi)始運(yùn)行,通過(guò)調(diào)用evenLock.await()來(lái)等待打印偶數(shù)的線(xiàn)程執(zhí)行。接著打印偶數(shù)的線(xiàn)程開(kāi)始運(yùn)行,當(dāng)輸出10個(gè)偶數(shù)或者沒(méi)有偶數(shù)輸出后,調(diào)用evenLock.signal()來(lái)通知打印奇數(shù)的線(xiàn)程開(kāi)始運(yùn)行,然后調(diào)用oddLock.wait方法來(lái)等待打印奇數(shù)的線(xiàn)程運(yùn)行完成。通過(guò)這種方法來(lái)控制奇數(shù)線(xiàn)程與偶數(shù)線(xiàn)程的運(yùn)行順序,實(shí)現(xiàn)代碼如下:

importjava.io.*;

importjava.util.Random;

importjava.util.concurrent.locks.Condition;

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

publicclassTest

{

privatestaticfinalintcount=10000;

privatestaticfinalintthreadGruopCount=5;

privatestaticfinalStringinputFile="testInput.txt";

publicstaticvoidgenerateTestFile()throwsIOException

{

//用隨機(jī)數(shù)生成10000個(gè)測(cè)試數(shù)據(jù)放到文件中

PrintWriterpw=newPrintWriter(newFileWriter(newFile(inputFile)),true);

Randomrandom=newRandom();

for(inti=0;i<count;i++)

{

pw.write(Math.abs(random.nextInt())%count+",");

}

pw.flush();

pw.close();

}

publicstaticvoidmain(String[]args)

{

try

{

generateTestFile();

BufferedReaderreader=newBufferedReader(newFileReader(inputFile));

Stringstr=reader.readLine();

reader.close();

String[]strs=str.split(",");

intindex=0;

//為了簡(jiǎn)單,每個(gè)文件輸出數(shù)字的個(gè)數(shù)相同

intcountForEachFile=count/threadGmopCount;

for(inti=0;i<threadGmopCount;i++)

{

intrecords[]=newint[countForEachFile];

for(intj=0;j<countForEachFile;j++)

{

records[j]=Integer.parseInt(strs[index]);

index++;

}

PrintGroupgroup=newPrintGroup(records,i);

group.startPrint();

}

}

catch(Exceptione)

{

e.printStackTrace();

}

}

}

classPrintGroup{

//這個(gè)線(xiàn)程組輸出數(shù)字的個(gè)數(shù)

privatestaticvolatileintcount=0;

privateLocklock=newReentrantLock();

privateConditionoddLock=lock.newCondition();

privateConditionevenLock=lock.newCondition();

//這個(gè)線(xiàn)程組需要輸出的數(shù)字?jǐn)?shù)組

privateintrecords[];

//這個(gè)線(xiàn)程組需要把數(shù)字輸出到同一個(gè)文件,因此,共享一個(gè)writer

//由于任意時(shí)刻只會(huì)有一個(gè)線(xiàn)程寫(xiě)文件,因此,不需要同步

privatePrintWriterwriter;

//記錄輸出奇數(shù)所在的數(shù)組下標(biāo)

privatevolatileintoddIndex=0;

//記錄輸出偶數(shù)所在的數(shù)組下標(biāo)

privatevolatileimevenlndex=0;

//輸出奇數(shù)的線(xiàn)程

privateOddPrintThreadoddPrintThread;

//輸出偶數(shù)的線(xiàn)程

privateEvenPrintThreadevenPrintThread;

privatevolatilebooleanfirst=true;

privateint[]result=newint[2000];

privateintindex=0;

publicPrintGroup(int[]records,intid)t

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論