| 摘 要: 多線程機(jī)制是Java的重要技術(shù),闡述了線程和進(jìn)程的差別;Java中線程4個(gè)狀態(tài)之間的轉(zhuǎn)換;并結(jié)合例子說(shuō)明了兩種創(chuàng)建線程的方法。 關(guān)鍵詞: 線程 消亡 阻塞 調(diào)度 線程是指程序中能順序執(zhí)行的一個(gè)序列。一個(gè)線程只有一個(gè)入口點(diǎn) 但可能有幾個(gè)出口點(diǎn) 不過(guò),每個(gè)時(shí)刻的執(zhí)行點(diǎn)總是只有一個(gè)。線程是不能獨(dú)立運(yùn)行的程序,而只是某個(gè)整體程序內(nèi)部的一個(gè)順序執(zhí)行流。 多線程是Java的一個(gè)重要特點(diǎn)。如果一個(gè)程序是單線程的,那么,任何時(shí)刻都只有一個(gè)執(zhí)行點(diǎn)。這種單線程執(zhí)行方法使系統(tǒng)運(yùn)行效率低,而且,由于必須依靠中斷來(lái)處理輸入/輸出。所以,當(dāng)出現(xiàn)頻繁輸入/輸出或者有優(yōu)先級(jí)較低的中斷請(qǐng)求時(shí),實(shí)時(shí)性就變得很差。多線程系統(tǒng)可以避免這個(gè)缺點(diǎn)。所謂多線程,就是通過(guò)系統(tǒng)的調(diào)度使幾個(gè)具有不同功能的程序流即線程同時(shí)并行地運(yùn)行。 在單處理器計(jì)算機(jī)系統(tǒng)中,實(shí)際上是不可能使多個(gè)線程真正并行運(yùn)行的,而要通過(guò)系統(tǒng)用極短的時(shí)間、極快的速度對(duì)多個(gè)線程進(jìn)行切換,宏觀上形成多個(gè)線程并發(fā)執(zhí)行的效果。 1 線程和進(jìn)程機(jī)制上的差別 線程和進(jìn)程很相象,它們都是程序的一個(gè)順序執(zhí)行序列,但兩者又有區(qū)別。進(jìn)程是一個(gè)實(shí)體,每個(gè)進(jìn)程有自己獨(dú)立的狀態(tài),并有自己的專用數(shù)據(jù)段,創(chuàng)建進(jìn)程時(shí), 必須建立和復(fù)制其專用數(shù)據(jù)段,線程則互相共享數(shù)據(jù)段。同一個(gè)程序中的所有線程只有一個(gè)數(shù)據(jù)段, 所以, 創(chuàng)建線程時(shí)不必重新建立和復(fù)制數(shù)據(jù)段。由于數(shù)據(jù)段建立和復(fù)制這方面的差異,使線程的建立和線程間的切換速度大大優(yōu)于進(jìn)程,另一方面,線程又具備進(jìn)程的大多數(shù)優(yōu)點(diǎn)。 假設(shè)銀行系統(tǒng)辦理存款和取款手續(xù),將帳本看成數(shù)據(jù)段。如果按進(jìn)程這種機(jī)制,那么,當(dāng)儲(chǔ)戶去存/取款時(shí),銀行應(yīng)先把帳本復(fù)制一遍,為儲(chǔ)戶建立一個(gè)獨(dú)立的帳本再結(jié)算。如果按線程機(jī)制, 那么,銀行里所有的出納員都用同一個(gè)帳本,儲(chǔ)戶來(lái)辦存/取款時(shí),也從這個(gè)帳本直接結(jié)算。用線程機(jī)制省去了數(shù)據(jù)段復(fù)制這一步顯然是線程獨(dú)具的特點(diǎn)。 由于多個(gè)線程共享一個(gè)數(shù)據(jù)段,所以,也出現(xiàn)了數(shù)據(jù)訪問(wèn)過(guò)程的互斥和同步問(wèn)題,這使系統(tǒng)管理功能變得相對(duì)復(fù)雜。 總的來(lái)說(shuō),一個(gè)多線程系統(tǒng)在提高系統(tǒng)的輸入/輸出速度、有效利用系統(tǒng)資源、改善計(jì)算機(jī)通信功能以及發(fā)揮多處理器硬件功能方面顯示了很大優(yōu)勢(shì)。因此,一些最新的操作系統(tǒng)如Windows95、Windows98、Windows NT等都提供了對(duì)多線程的支持。但是,在多線程操作系統(tǒng)下設(shè)計(jì)多線程的程序仍然是一個(gè)比較復(fù)雜和困難的工作。由于需要解決對(duì)數(shù)據(jù)段的共享,所以,原則上應(yīng)該從程序設(shè)計(jì)角度采用加鎖和釋放措施,稍有不慎,便會(huì)使系統(tǒng)產(chǎn)生管理上的混亂。 而Java從語(yǔ)言一級(jí)提供對(duì)多線程的支持,這樣,可由語(yǔ)言和運(yùn)行系統(tǒng)聯(lián)合提供對(duì)共享數(shù)據(jù)段的管理功能和同步機(jī)制,使得多線程并行程序設(shè)計(jì)相對(duì)比較容易。 2 Java線程的生命周期 每個(gè)線程都是和生命周期相聯(lián)系的,一個(gè)生命周期含有多個(gè)狀態(tài),這些狀態(tài)間可以互相轉(zhuǎn)化。 Java的線程的生命周期可以分為4個(gè)狀態(tài);創(chuàng)建(new)狀態(tài);可運(yùn)行(runnable)狀態(tài);不執(zhí)行(notrunnable)狀態(tài);消亡(dead)狀態(tài)。 創(chuàng)建狀態(tài)是指創(chuàng)建一個(gè)線程對(duì)應(yīng)的對(duì)象的過(guò)程,Java系統(tǒng)中,些對(duì)象都是從Java.lang包內(nèi)一個(gè)稱為Thread的類用關(guān)鍵字new創(chuàng)建的。剛創(chuàng)建的線程不能執(zhí)行,必須向系統(tǒng)進(jìn)行注冊(cè)、分配必要的資源后才能進(jìn)入可運(yùn)行狀態(tài),這個(gè)步驟是由start操作完成的,而處于可運(yùn)行狀態(tài)的線程也未必一定處于運(yùn)行中,它有可能由于外部的I/O請(qǐng)求而處于不運(yùn)行狀態(tài)。進(jìn)入消亡狀態(tài)后,此線程就不再存在了。 一個(gè)線程創(chuàng)建之后,總是處于其生命周期的4個(gè)狀態(tài)之一中,線程的狀態(tài)表明此線程當(dāng)前正在進(jìn)行的活動(dòng),而線程的狀態(tài)是可以通過(guò)程序來(lái)進(jìn)行控制的,就是說(shuō),可以對(duì)線程進(jìn)行操作來(lái)改變狀態(tài)。 這些操作包括啟動(dòng)(start)、終止(stop)、睡眠(sleep)、掛起(suspend)、恢復(fù)(resume)、等待(wait)和通知(notify)。每一個(gè)操作都對(duì)應(yīng)了一個(gè)方法 這些方法是由軟件包Java.lang提供的。通過(guò)各種操作,線程的4個(gè)狀態(tài)之間可按圖1所示進(jìn)行轉(zhuǎn)換。 2.1 創(chuàng)建(new)狀態(tài) 如果創(chuàng)建了一個(gè)線程而沒(méi)有啟動(dòng)它,那么,此線程就處于創(chuàng)建狀態(tài)。比如,下述語(yǔ)句執(zhí)行以后,使系統(tǒng)有了一個(gè)處于創(chuàng)建狀態(tài)的線程myThread: Thread myThread=new MyThreadClass(); 其中,MyThreadClass()是Thread的子類,而Thread是由Java系統(tǒng)的Java.lang軟件包提供的。處于創(chuàng)建狀態(tài)的線程還沒(méi)有獲得應(yīng)有的資源,所以,這是一個(gè)空的線程,線程只有通過(guò)啟動(dòng)后,系統(tǒng)才會(huì)為它分配資源。對(duì)處于創(chuàng)建狀態(tài)的線程可以進(jìn)行兩種操作: 一是啟動(dòng)(start)操作,使其進(jìn)入可運(yùn)行狀態(tài);二是終止(stop)操作,使其進(jìn)入消亡狀態(tài)。如果進(jìn)入到消亡狀態(tài),那么,此后這個(gè)線程就不能進(jìn)入其它狀態(tài),也就是說(shuō),它不復(fù)存在了。 |