国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

Java多線程機(jī)制實(shí)現(xiàn)及其應(yīng)用

2009-04-21 06:44聞麗華
消費(fèi)導(dǎo)刊 2009年6期
關(guān)鍵詞:多線程

[摘 要]本文就如何實(shí)現(xiàn)Java 的多線程、線程調(diào)度模式、同步互斥機(jī)制以及內(nèi)置多線程功能進(jìn)行了深入的探討,并對(duì)線程的狀態(tài)、創(chuàng)建和控制方法以及避免死鎖的方法作了歸納總結(jié),指出了線程實(shí)際應(yīng)用領(lǐng)域以及在編程時(shí)應(yīng)注意的事項(xiàng)。

[關(guān)鍵詞]多線程 線程調(diào)度 同步機(jī)制 死鎖

作者簡(jiǎn)介:聞麗華(1969-),女,大連水產(chǎn)學(xué)院職業(yè)技術(shù)學(xué)院 計(jì)算機(jī)系講師 工程碩士學(xué)位。

引入線程是十分必要的,線程共享相同的地址空間并共同構(gòu)成一個(gè)大的進(jìn)程,所以同一進(jìn)程中的線程間的通訊是非常簡(jiǎn)單而有效的,上下文切換非??觳⑶沂钦麄€(gè)大程序的一部分切換。線程僅是過(guò)程調(diào)用,它們彼此獨(dú)立執(zhí)行,線程使得在一個(gè)應(yīng)用程序中同時(shí)使用多個(gè)線程來(lái)完成不同的任務(wù),程序的編寫(xiě)更加自由和豐富,可以大大簡(jiǎn)化應(yīng)用程序設(shè)計(jì)。如果要一程序中實(shí)現(xiàn)多段代碼同時(shí)交替運(yùn)行,就需要產(chǎn)生多個(gè)線程,并指定每個(gè)線程上所要運(yùn)行的程序代碼段,這就是多線程。多線程可以增進(jìn)程序的交互性, 提供更好功能、更好的GUI 和更好的服務(wù)器功能。

Java 在兩方面支持多線程,一方面,Java 環(huán)境本身就是多線程的,若干個(gè)系統(tǒng)線程運(yùn)行負(fù)責(zé)必要的無(wú)用單元回收, 系統(tǒng)維護(hù)等系統(tǒng)級(jí)操作;另一方面,Java 語(yǔ)言內(nèi)置多線程控制, 可以大大簡(jiǎn)化多線程應(yīng)用程序開(kāi)發(fā)。

一、Java 中如何實(shí)現(xiàn)多線程

Java 的多線程機(jī)制使得在一個(gè)程序里可同時(shí)執(zhí)行多個(gè)任務(wù)。 只有在多CPU 的計(jì)算機(jī)或者在網(wǎng)絡(luò)計(jì)算體系結(jié)構(gòu)下,將Java 程序劃分為多個(gè)并發(fā)執(zhí)行線程后,同時(shí)啟動(dòng)多個(gè)線程運(yùn)行,使不同的線程運(yùn)行在基于不同處理器的Java虛擬機(jī)中,才能提高應(yīng)用程序的執(zhí)行效率。

(一)Java多線程實(shí)現(xiàn)方法

Java 采用兩種途徑實(shí)現(xiàn)多線程機(jī)制:一種是應(yīng)用程序的并發(fā)運(yùn)行對(duì)象直接繼承Thread 類,另外一種是定義并發(fā)執(zhí)行對(duì)象實(shí)現(xiàn)Runnable 接口。

1.用Thread 類創(chuàng)建線程

Java的線程是通過(guò)java.lang.Thread類來(lái)控制的,一個(gè)Thread類的對(duì)象代表一個(gè)線程。當(dāng)編寫(xiě)Thread 類的子類時(shí),在子類中重寫(xiě)父類的run()方法,該方法中包含了線程的操作,這樣的程序需要建立自己的線程時(shí),只需要?jiǎng)?chuàng)建一個(gè)已定義好的Thread 子類的實(shí)例就可以了,當(dāng)創(chuàng)建的線程需要調(diào)用start()方法開(kāi)始運(yùn)行時(shí),run()方法將被自動(dòng)執(zhí)行。

2.使用Runnable 接口創(chuàng)建多線程

通過(guò)實(shí)現(xiàn)Runnable 作為一個(gè)目標(biāo)對(duì)象,用Runnable 目標(biāo)對(duì)象初始化Thread 類,提供run()方法,實(shí)現(xiàn)的同時(shí)還可以繼承其他類,可以避免由單繼承的局限。幾乎所有的線程都可以用Runnable 接口。當(dāng)線程被構(gòu)造時(shí), 需要的代碼和數(shù)據(jù)通過(guò)一個(gè)對(duì)象作為構(gòu)造函數(shù)實(shí)參傳遞進(jìn)去, 這個(gè)對(duì)象就是實(shí)現(xiàn)了Runnable接口的類的實(shí)例。

3.兩種方法的對(duì)比分析

直接繼承Thread 類的方法不能再?gòu)钠渌惱^承,編寫(xiě)簡(jiǎn)單,可以直接操作線程;實(shí)現(xiàn)Runnable 接口的方法適合多個(gè)相同程序代碼的線程去處理同一資源的情況,可以避免由于Java單繼承特性帶來(lái)的局限。兩者的重要區(qū)別在于啟動(dòng)多線程對(duì)象的設(shè)計(jì)方法不同。在具體應(yīng)用中,采用哪種方法來(lái)構(gòu)造線程要視情況而定。事實(shí)上,幾乎所有多線程應(yīng)用都可用第二種方式,即實(shí)現(xiàn)Runnable接口。

(二)線程的狀態(tài)控制

線程包括四個(gè)狀態(tài):new (開(kāi)始),running (運(yùn)行),wait (等候)和done(結(jié)束)。當(dāng)線程被創(chuàng)建并還未運(yùn)行時(shí), 線程處于new 狀態(tài), 在這個(gè)狀態(tài)下,線程不能運(yùn)行。對(duì)于新創(chuàng)建的線程,調(diào)用start 方法之后, 會(huì)自動(dòng)調(diào)用start 方法,這時(shí)線程進(jìn)入就緒狀態(tài)。在程序之間用某種方法把處理器的執(zhí)行時(shí)間分成時(shí)間片, 位于就緒狀態(tài)的每個(gè)線程都是能運(yùn)行的,但在某一時(shí)刻, 系統(tǒng)處理器只能運(yùn)行一個(gè)線程。由于某些原因, 線程可以被臨時(shí)暫停進(jìn)入等候狀態(tài)。處于這種狀態(tài)的線程,對(duì)于用戶來(lái)講仍然有效,仍然可以重新進(jìn)入就緒狀態(tài)。當(dāng)線程因不再需要而進(jìn)入結(jié)束狀態(tài)時(shí),線程就不能再被恢復(fù)和執(zhí)行。

(三)線程的調(diào)度機(jī)制

為了控制線程的運(yùn)行,Java定義了線程調(diào)度器來(lái)監(jiān)控系統(tǒng)中處于就緒狀態(tài)的所有線程。 線程調(diào)度器按照線程的優(yōu)先級(jí)決定那個(gè)線程投入處理器運(yùn)行,在多個(gè)線程處于就緒狀態(tài)的條件下,具有高優(yōu)先級(jí)的線程會(huì)在低優(yōu)先級(jí)線程之前得到執(zhí)行,線程調(diào)度器同樣采用“搶占式”策略來(lái)調(diào)度線程執(zhí)行,即當(dāng)前線程執(zhí)行過(guò)程中有較高優(yōu)先級(jí)的線程進(jìn)入就緒狀態(tài),則高優(yōu)先級(jí)的線程立即被調(diào)度執(zhí)行,具有相同優(yōu)先級(jí)的所有線程采用輪轉(zhuǎn)的方式來(lái)共同分配CPU 時(shí)間片。

線程調(diào)度的意義在于避免多個(gè)線程爭(zhēng)用有限資源而導(dǎo)致應(yīng)用系統(tǒng)死機(jī)或者崩潰。Java 支持搶占式調(diào)度,因此線程的優(yōu)先級(jí)尤為重要,它是線程調(diào)度的決策依據(jù)。Java 中線程的優(yōu)先級(jí)分為10 個(gè)等級(jí),分別用1~10 之間的數(shù)字表示,數(shù)字越大表明線程的級(jí)別越高,線程創(chuàng)建時(shí),子線程繼承父線程的優(yōu)先級(jí)。線程運(yùn)行的順序以及從處理器中獲得的時(shí)間數(shù)量主要取決于開(kāi)發(fā)者, 處理器給每個(gè)線程分配一個(gè)時(shí)間片, 而且線程的運(yùn)行不能影響整個(gè)系統(tǒng)。處理器線程的系統(tǒng)或者是搶占式的, 或者是非搶占式的。搶占式系統(tǒng)在任何給定的時(shí)間內(nèi)將運(yùn)行最高優(yōu)先級(jí)的線程, 系統(tǒng)中的所有線程都有自己的優(yōu)先級(jí)。Thread 類提供了setPriority 和getPriority方法來(lái)重新設(shè)置和讀取優(yōu)先權(quán)。Java 虛擬機(jī)是搶占式的, 它能保證運(yùn)行優(yōu)先級(jí)最高的線程。

Java 通過(guò)創(chuàng)建了線程組管理成百上千個(gè)線程。線程組是線程的一個(gè)譜系組, 每個(gè)組包含的線程數(shù)不受限制,能對(duì)每個(gè)線程命名并能在整個(gè)線程組中執(zhí)行(Suspend)和停止(Stop)這樣的操作。

(四)多線程的同步機(jī)制

Java 應(yīng)用程序的多個(gè)線程共享同一進(jìn)程的數(shù)據(jù)資源,多個(gè)用戶線程在并發(fā)運(yùn)行過(guò)程中可能同時(shí)訪問(wèn)具有敏感性的內(nèi)容,競(jìng)爭(zhēng)共享資源。必須采用某種方法來(lái)確定資源在某一時(shí)刻僅被一個(gè)線程占用,達(dá)到此目的的過(guò)程叫同步(synchronized),在Java 中定義了線程同步的概念,實(shí)現(xiàn)對(duì)共享資源的一致性維護(hù)。多線程同步機(jī)制的實(shí)現(xiàn)是基于管程 (Monitor)機(jī)制。 管程是一個(gè)互斥獨(dú)占鎖定的對(duì)象,或稱互斥體。 在給定的時(shí)間里,僅有一個(gè)線程可以獲得管程。所有其他試圖進(jìn)入已經(jīng)鎖定的管程的線程必須掛起,當(dāng)擁有管程的線程從同步方法中返回或異常退出時(shí),其他線程才可以獲得管程??梢杂胹ynchronized 和Object 類的方法wait ()、notify()和notifyAll()實(shí)現(xiàn)多線程同步。 線程同步有同步方法和同步語(yǔ)句兩種: (1)同步方法。 在方法的聲明中用synchronized 關(guān)鍵字修飾,可以對(duì)該方法中的所有代碼實(shí)現(xiàn)同步,其格式為public synchronized void method (){...}. (2)同步語(yǔ)句。 用synchronized 關(guān)鍵字修飾的程序塊稱同步語(yǔ)句或同步塊。 當(dāng)需要調(diào)用某個(gè)類中的方法,而該類沒(méi)有同步方法,但又必須實(shí)現(xiàn)同步時(shí),就要采用同步語(yǔ)句。 只要將對(duì)這個(gè)類定義的方法的調(diào)用放入一個(gè)synchronized 塊內(nèi)就可以了,其格式為: synchronized (object){...},其中,object 是對(duì)同步對(duì)象的引用。從經(jīng)過(guò)線程同步機(jī)制定義后的代碼形式可以看出:在對(duì)共享資源進(jìn)行訪問(wèn)的方法訪問(wèn)屬性關(guān)鍵字(public)后附加同步定義關(guān)鍵字synchronized,使得同步方法在對(duì)共享資源訪問(wèn)的時(shí)候,為這些敏感資源附加共享鎖來(lái)控制方法執(zhí)行期間的資源獨(dú)占性,實(shí)現(xiàn)了應(yīng)用系統(tǒng)數(shù)據(jù)資源的一致性管理和維護(hù)。

(五)避免死鎖

死鎖是一個(gè)經(jīng)典的多線程問(wèn)題,它是一種少見(jiàn)的、而且難于調(diào)試的錯(cuò)誤,在兩個(gè)線程對(duì)兩個(gè)同步對(duì)象具有循環(huán)依賴時(shí),就會(huì)出現(xiàn)死鎖。因?yàn)椴煌木€程都在等待那些根本不可能被釋放的鎖,從而導(dǎo)致所有的工作都無(wú)法完成。死鎖不是資源不夠引起的,而是由線程的調(diào)度引起的,對(duì)于死鎖可用下述方法解決: (1)嘗試在盡可能短的時(shí)間內(nèi)執(zhí)行鎖定的代碼,占用時(shí)間越長(zhǎng),另一個(gè)線程出現(xiàn)和需要對(duì)象的可能性越大;(2)當(dāng)你從另一個(gè)被同步的方法中激活被同步的方法時(shí)要小心,最好是清楚地定義每個(gè)線程的任務(wù),并考慮使用什么數(shù)據(jù)和什么時(shí)間使用。

二、多線程的應(yīng)用

在實(shí)際應(yīng)用中,線程使用的范圍很廣,可用于控制實(shí)時(shí)數(shù)據(jù)處理、快速的網(wǎng)絡(luò)服務(wù),還有更快的圖像繪制和打印,以及數(shù)據(jù)庫(kù)中數(shù)據(jù)的取回和處理等等。 在Java 中有些線程在不停運(yùn)行,提供一些基本服務(wù),其中一個(gè)典型的例子就是垃圾收集線程( GarbageCollectionThread )。 該線程由Java虛擬機(jī)(JVM )提供,由一個(gè)中心線程控制執(zhí)行,它掃描程序中不再被訪問(wèn)的變量,將其所占的系統(tǒng)資源釋放給系統(tǒng),當(dāng)Java 線程請(qǐng)求存儲(chǔ)時(shí),如果Java 虛擬機(jī)不能分配足夠的存儲(chǔ)塊來(lái)滿足這個(gè)請(qǐng)求,則可以說(shuō)出現(xiàn)了分配失敗,這就不可避免要進(jìn)行垃圾回收。結(jié)合Java 的多線程應(yīng)用及其它特性,如平臺(tái)無(wú)關(guān)性、對(duì)網(wǎng)絡(luò)強(qiáng)有力的支持,特別是Sun 公司對(duì)Java 語(yǔ)言進(jìn)行了擴(kuò)充,引入了遠(yuǎn)程方法調(diào)用RMI 機(jī)制,它提供了在并行計(jì)算環(huán)境下應(yīng)用Java 語(yǔ)言的一些基本功能。由此可見(jiàn),Java 在分布式計(jì)算、并行計(jì)算方面將大有作為。

三、使用多線程應(yīng)注意的問(wèn)題

利用多線程的并發(fā)執(zhí)行特點(diǎn),無(wú)疑會(huì)加快程序的運(yùn)行,提高CPU 、內(nèi)存等系統(tǒng)資源的使用效率,但在應(yīng)用多線程時(shí),要注意同時(shí)運(yùn)行在內(nèi)存中的多個(gè)線程之間的關(guān)系。由于線程執(zhí)行不受建立先后的約束,線程間共享數(shù)據(jù)可能會(huì)出現(xiàn)程序員想象不到的事情,還有多個(gè)線程同時(shí)訪問(wèn)修改同一個(gè)數(shù)據(jù)、資源競(jìng)爭(zhēng)和死鎖問(wèn)題,都需要程序員周密的考慮??傮w來(lái)說(shuō),在程序中使用多線程需要考慮以下幾個(gè)問(wèn)題:

(一)創(chuàng)建線程需要占用更多的內(nèi)存資源;

(二)創(chuàng)建線程需要增加CPU 跟蹤線程、切換線程的時(shí)間開(kāi)銷;

(三)多線程編程必須考慮資源共享問(wèn)題、同時(shí)訪問(wèn)通訊端口問(wèn)題以及系統(tǒng)資源競(jìng)爭(zhēng)和死鎖問(wèn)題;

(四)同一任務(wù)下的多個(gè)線程同時(shí)訪問(wèn)和修改某個(gè)數(shù)據(jù)時(shí),要考慮數(shù)據(jù)的安全問(wèn)題。由此看出,線程不是越多越好,而是要適度,并且對(duì)多線程編程的程序員也提高了要求。總之,多線程會(huì)使軟件編程變得更加靈活,同時(shí)也給程序員帶來(lái)了更大的機(jī)遇和挑戰(zhàn)。

四、結(jié)束語(yǔ)

由于Java 的多線程功能齊全, 它帶來(lái)的好處也是顯然易見(jiàn)的。在開(kāi)發(fā)難易程度和性能上都比單線程要好。另一方面,由于多線程還沒(méi)有充分利用基本操作系統(tǒng)的這一功能,對(duì)于不同的系統(tǒng), 上面的程序可能會(huì)出現(xiàn)截然不同的結(jié)果, 這使編程者偶會(huì)感到迷惑不解。

實(shí)際運(yùn)用時(shí),要充分考慮多線程編程的復(fù)雜性以及線程切換開(kāi)銷帶來(lái)的多線程程序的低效性,要注意是否需要多線程,就是要看這是否也是它的內(nèi)在特點(diǎn),只有當(dāng)完全符合多線程的特點(diǎn)時(shí),多線程機(jī)制對(duì)線程間通信和線程管理的強(qiáng)大支持才能有用武之地,這時(shí)使用多線程才是值得的。實(shí)際上, 無(wú)論是系統(tǒng)級(jí)還是語(yǔ)言級(jí)的多線程, 如果操作系統(tǒng)本身不支持多線程,Java 的多線程就可能只是受限的或不完全的多線程。

參考文獻(xiàn)

[1]盧俊嶺,師軍,基于Java 的多線程機(jī)制[J]陜西師范大學(xué)學(xué)報(bào)(自然科學(xué)版) ,2000, (4)

[2]馬紅霞,張春芳,JAVA 與多線程程序設(shè)計(jì)[J]河北工業(yè)科技,2004, (4)

[3]王克宏,Java 技術(shù)教程(基礎(chǔ)篇) [M] 北京:清華大學(xué)出版社,2005

[4]耿祥義,張躍平,Java 2 實(shí)用教程[M]北京:清華大學(xué)出版社,2006.8

猜你喜歡
多線程
Java多線程同步機(jī)制在網(wǎng)絡(luò)售票系統(tǒng)中的應(yīng)用
Java并發(fā)工具包對(duì)并發(fā)編程的優(yōu)化
基于多線程文件傳輸關(guān)鍵技術(shù)研究與實(shí)現(xiàn)
網(wǎng)頁(yè)爬蟲(chóng)技術(shù)的關(guān)鍵技術(shù)研究探索
一種基于多線程的高速磁盤(pán)鏡像算法
iOS并發(fā)程序設(shè)計(jì)中幾種方法的特點(diǎn)及使用技巧研究
HTM L5 Web WOrker技術(shù)及應(yīng)用研究
電站鍋爐煤粉參數(shù)遠(yuǎn)程監(jiān)控系統(tǒng)的軟件設(shè)計(jì)與實(shí)現(xiàn)
一種高并發(fā)認(rèn)證服務(wù)器的實(shí)現(xiàn)
一種低開(kāi)銷的并行重復(fù)數(shù)據(jù)刪除算法
沙坪坝区| 井研县| 安仁县| 宁河县| 四平市| 独山县| 雷波县| 昌乐县| 昆明市| 中方县| 白沙| 洞口县| 临西县| 九江县| 长垣县| 监利县| 个旧市| 观塘区| 循化| 梧州市| 年辖:市辖区| 漾濞| 山丹县| 延安市| 游戏| 绥芬河市| 巴马| 灌阳县| 河南省| 北票市| 宁夏| 石台县| 凉城县| 城固县| 漯河市| 读书| 开封市| 武冈市| 安阳县| 广丰县| 平潭县|