亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        淺析Java多線程機(jī)制

        2008-12-31 00:00:00王鈞玉王獻(xiàn)宏
        電腦知識(shí)與技術(shù) 2008年19期

        摘要:本文在對(duì)Java多線程分析的基礎(chǔ)上,針對(duì)如何實(shí)現(xiàn)多線程,如何進(jìn)行同步,如何管理多線程等問(wèn)題進(jìn)行了簡(jiǎn)單的闡述。

        關(guān)鍵詞:線程;多線程;線程組

        中圖分類號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)19-30181-03

        Analyse Shallowly Java Multi-threading Mechanism

        WANG Jun-yu, WANG Xian-hong

        (Sanmenxia Vocational and Technical College, Sanmenxia 472000, China)

        Abstract: This text is based on the analysis of Java multi-threading mechanism, aim at how to carry out a multi-threading, how to carry on synchronously, how to manage multi-threading's etc.'s problem to carry on to expound in brief.

        Key words: thread; multi-threading; thread group

        1 理解多線程

        傳統(tǒng)的程序大多是單線程的,即一個(gè)程序只有一條從頭至尾的執(zhí)行線索。然而現(xiàn)實(shí)世界中的很多過(guò)程都具有多條線索同時(shí)動(dòng)作的特性。例如:我們可以一邊看書,一邊擺動(dòng)胳膊,如果不容許這樣做,我們會(huì)感覺(jué)很難受。再如一個(gè)網(wǎng)絡(luò)服務(wù)器可能需要同時(shí)處理多個(gè)客戶機(jī)的請(qǐng)求等。

        Java語(yǔ)言的一大特性就是內(nèi)置對(duì)多線程的支持。多線程是這樣的一種機(jī)制,它允許在程序中并發(fā)執(zhí)行多個(gè)指令流,每個(gè)指令流都稱為一個(gè)線程,彼此間互相獨(dú)立。線程又稱為輕量級(jí)進(jìn)程,它和進(jìn)程一樣擁有獨(dú)立的執(zhí)行控制,由操作系統(tǒng)負(fù)責(zé)調(diào)度,區(qū)別在于線程沒(méi)有獨(dú)立的存儲(chǔ)空間,而是和所屬進(jìn)程中的其它線程共享一個(gè)存儲(chǔ)空間,這使得線程間的通信遠(yuǎn)較進(jìn)程簡(jiǎn)單。

        多個(gè)線程是并發(fā)執(zhí)行的,也就是在邏輯上“同時(shí)”,而不管是否是物理上的“同時(shí)”。若系統(tǒng)只有一個(gè)CPU,真正的“同時(shí)”是不可能的,但是由于CPU的速度非??欤脩舾杏X(jué)不到其中的區(qū)別,因此我們也不用關(guān)心它,只需要設(shè)想各個(gè)線程是同時(shí)執(zhí)行的即可。多線程和傳統(tǒng)的單線程在程序設(shè)計(jì)上最大的區(qū)別在于,由于各個(gè)線程的控制流彼此獨(dú)立,為了建立這些線程正在同步執(zhí)行的感覺(jué),Java快速地把控制從一個(gè)線程切換到另一個(gè)線程。

        2 線程與程序、進(jìn)程的區(qū)別

        程序是一段靜態(tài)的代碼,它是應(yīng)用軟件執(zhí)行的藍(lán)本。

        進(jìn)程是程序的一次動(dòng)態(tài)執(zhí)行過(guò)程,它對(duì)應(yīng)了從代碼加載、執(zhí)行至執(zhí)行完畢的一個(gè)完整過(guò)程,這個(gè)過(guò)程也是進(jìn)程本身從產(chǎn)生、發(fā)展至消亡的過(guò)程。如果把銀行一天的工作比作一個(gè)進(jìn)程,那么早上打鈴上班是進(jìn)程的開始,晚上打下班鈴是進(jìn)程的結(jié)束。

        線程是比進(jìn)程更小的執(zhí)行單位。盡管線程在一些程序語(yǔ)言中又稱為進(jìn)程,但是基本的思想是相同的:一個(gè)線程是一個(gè)運(yùn)行在后臺(tái)的、獨(dú)立于主應(yīng)用程序的任務(wù)[2]。所有的程序至少自動(dòng)擁有一個(gè)線程。這個(gè)線程稱為主線程,當(dāng)程序加載到內(nèi)存中時(shí),啟動(dòng)主線程。要加載第二個(gè)、第三個(gè)或者第四個(gè)線程,程序就要使用Thread類和Runnable接口。

        3 在Java中實(shí)現(xiàn)多線程

        在Java中實(shí)現(xiàn)多線程有兩個(gè)途徑:繼承Thread類和實(shí)現(xiàn)Runnable接口。

        3.1 繼承Thread類的多線程程序設(shè)計(jì)方法

        Thread 類是JDK中定義的用于控制線程對(duì)象的類,在該類中封裝了用于進(jìn)行線程控制的方法。見下面的示例代碼:

        import java.util.*;

        class TimePrinter extends Thread {

        int pauseTime;

        String name;

        public TimePrinter(int x, String n) {

        pauseTime = x;

        name = n;

        }

        public void run() {

        while(true) {

        try {

        System.out.println(name + \":\" + new

        Date(System.currentTimeMillis()));

        Thread.sleep(pauseTime);

        } catch(Exception e) {

        System.out.println(e);}}}

        static public void main(String args[]) {

        TimePrinter tp1 = new TimePrinter(1000, \"Fast Guy\");

        tp1.start();

        TimePrinter tp2 = new TimePrinter(3000, \"Slow Guy\");

        tp2.start();}}

        這種方法簡(jiǎn)單明了,符合我們的習(xí)慣,但它有一個(gè)很大的缺點(diǎn),那就是如果我們創(chuàng)建的類已經(jīng)從一個(gè)類繼承(如小程序必須繼承自 Applet 類),那么無(wú)法再繼承 Thread 類,而這時(shí)我們又不想建立一個(gè)新的類,怎么辦呢?我們可以這樣做:就是不創(chuàng)建 Thread 類的子類,而是直接使用它,若直接使用Thread類,那就需要Runnable接口支持。雖然抽象類也可滿足,但需要繼承,為了避免繼承帶來(lái)的限制,則只有使用Java 提供的接口 java.lang.Runnable 來(lái)支持。

        3.2 實(shí)現(xiàn)Runnable接口的多線程程序設(shè)計(jì)方法

        Java語(yǔ)言中提供的另外一種實(shí)現(xiàn)多線程應(yīng)用程序的方法是多線程對(duì)象實(shí)現(xiàn)Runnable接口并且在該類中定義用于啟動(dòng)線程的run方法。這種定義方式的好處在于多線程應(yīng)用對(duì)象可以繼承其它對(duì)象而不是必須繼承Thread類,從而能夠增加類定義的邏輯性。實(shí)現(xiàn)Runnable接口的多線程應(yīng)用程序如下所示:

        public class MyThread implements Runnable {

        int count= 1, number;

        public MyThread(int num) {

        number = num;

        System.out.println(\"創(chuàng)建線程 \" + number);

        }

        public void run() {

        while(true) {

        System.out.println(\"線程 \" + number + \":計(jì)數(shù) \" + count);

        if(++count== 6) return;

        } }

        public static void main(String args[]) {

        for(int i = 0; i < 5; i++) new Thread(new MyThread(i+1)).start();}}

        使用 Runnable 接口來(lái)實(shí)現(xiàn)多線程使得我們能夠在一個(gè)類中包容所有的代碼,有利于封裝,它的缺點(diǎn)在于,我們只能使用一套代碼,若想創(chuàng)建多個(gè)線程并使各個(gè)線程執(zhí)行不同的代碼,則仍必須額外創(chuàng)建類,如果這樣的話,在大多數(shù)情況下也許還不如直接用多個(gè)類分別繼承 Thread 來(lái)得緊湊。這兩種方法,各有千秋,可靈活使用。

        4 線程間的同步

        由于同一進(jìn)程的多個(gè)線程共享同一片存儲(chǔ)空間,在帶來(lái)方便的同時(shí),也帶來(lái)了訪問(wèn)沖突這個(gè)嚴(yán)重的問(wèn)題。比如一個(gè)工資管理負(fù)責(zé)人正在修改雇員的工資表,而一些雇員也正在領(lǐng)取工資,如果容許這樣做必然出現(xiàn)混亂。因此工資管理負(fù)責(zé)人正在修改工資表時(shí)(包括他喝茶休息一會(huì)),將不容許任何雇員領(lǐng)取工資,也就是說(shuō)這些雇員必須等待。如在沒(méi)有多線程同步控制策略條件下的代碼:

        public class SharedResouce {

        private int a = 0;

        private int b = 0;

        public void setA(int a) { this.a = a; }

        public void setB(int b) { this.b = b; }

        }

        由于未加鎖setA()時(shí),可以setB(),setB()時(shí)可以setA()。這時(shí)兩個(gè)以上的線程同時(shí)執(zhí)行,會(huì)引發(fā)沖突。因此在Java中定義了線程同步的概念,用synchronized關(guān)鍵字為共享資源加鎖來(lái)解決同步的問(wèn)題,實(shí)現(xiàn)對(duì)共享資源的一致性維護(hù)。進(jìn)行線程同步策略控制后的程序代碼如下所示:

        public class SharedResouce {

        private int a = 0;

        private int b = 0;

        public void synchronized setA(int a) { this.a = a; }

        public void synchronized setB(int b) { this.b = b; }

        }

        同步整個(gè)方法,則setA()的時(shí)候無(wú)法setB(),setB()時(shí)無(wú)法setA()。也就是說(shuō),在任何一個(gè)時(shí)刻只能有一個(gè)線程訪問(wèn)setA()或者setB()。

        5 Java線程的管理

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

        要想實(shí)現(xiàn)多線程,必須在主線程中創(chuàng)建新的線程對(duì)象,新建的線程對(duì)象在它的一個(gè)完整的生命周期中通常要經(jīng)歷5種狀態(tài)。在控制線程從一種狀態(tài)轉(zhuǎn)入另一種狀態(tài)時(shí),必須調(diào)用正確的方法,如果調(diào)用的方法錯(cuò)誤,就會(huì)產(chǎn)生一些異常[1]。5種狀態(tài)如下:

        新建狀態(tài):當(dāng)一個(gè)Thread類或其子類的對(duì)象被聲明并創(chuàng)建時(shí),新生的線程對(duì)象處于新建狀態(tài)。此時(shí)它已經(jīng)有了相應(yīng)的內(nèi)存空間和其他資源。

        就緒狀態(tài):在處于新建狀態(tài)的線程中調(diào)用start方法將線程的狀態(tài)轉(zhuǎn)換為就緒狀態(tài)。這時(shí),線程已經(jīng)得到除CPU時(shí)間之外的其它系統(tǒng)資源,只等JVM的線程調(diào)度器按照線程的優(yōu)先級(jí)對(duì)該線程進(jìn)行調(diào)度,從而使該線程擁有能夠獲得CPU時(shí)間片的機(jī)會(huì)。

        運(yùn)行狀態(tài):當(dāng)就緒的線程被調(diào)度并獲得處理器資源時(shí),便進(jìn)入運(yùn)行狀態(tài)。

        阻塞狀態(tài):一個(gè)正在運(yùn)行的線程因某種原因不能繼續(xù)運(yùn)行時(shí),進(jìn)入阻塞狀態(tài)。

        死亡狀態(tài):處于死亡狀態(tài)的線程不具有繼續(xù)運(yùn)行的能力。線程死亡的原因有二,一個(gè)是正常運(yùn)行的線程完成了它的全部工作,即執(zhí)行完了run()方法的最后一個(gè)語(yǔ)句并退出,另一個(gè)是線程被提前強(qiáng)制性的終止。

        5.2 線程的調(diào)度

        線程調(diào)用的意義在于JVM應(yīng)對(duì)運(yùn)行的多個(gè)線程進(jìn)行系統(tǒng)級(jí)的協(xié)調(diào),以避免多個(gè)線程爭(zhēng)用有限資源而導(dǎo)致應(yīng)用系統(tǒng)死機(jī)或者崩潰。

        處于就緒狀態(tài)的線程首先進(jìn)入就緒隊(duì)列排隊(duì)處理器資源,同一時(shí)刻在就緒隊(duì)列中的線程可能有多個(gè)。多線程系統(tǒng)會(huì)給每個(gè)線程自動(dòng)分配一個(gè)線程的優(yōu)先級(jí),任務(wù)較緊急的重要線程,其優(yōu)先級(jí)就較高;相反則較低。在線程排隊(duì)時(shí),優(yōu)先級(jí)高的線程可以排在較前的位置,能優(yōu)先享用到處理器資源,而優(yōu)先級(jí)較低的線程則只能等到排在它前面的高優(yōu)先級(jí)線程執(zhí)行完畢之后才能獲得處理器資源。對(duì)于優(yōu)先級(jí)相同的線程,則遵循隊(duì)列的“先進(jìn)先出”的原則,即先進(jìn)入就緒狀態(tài)排隊(duì)的線程被優(yōu)先分配到處理器資源,隨后才后進(jìn)入隊(duì)列的線程服務(wù)。

        當(dāng)一個(gè)在就緒隊(duì)列中排隊(duì)的線程被分配到處理器資源而進(jìn)入運(yùn)行狀態(tài)之后,這個(gè)線程就稱為是被“調(diào)度”或被線程調(diào)度管理器選中了。線程調(diào)度管理器負(fù)責(zé)管理線程排隊(duì)和處理器在線程間的分配,一般都配有一個(gè)精心設(shè)計(jì)的線程調(diào)度算法。在Java系統(tǒng)中,線程調(diào)度依據(jù)優(yōu)先級(jí)基礎(chǔ)上的“先到先服務(wù)”的原則。

        5.3 線程分組管理

        Java定義了在多線程運(yùn)行系統(tǒng)中的線程組(ThreadGroup)對(duì)象,用于實(shí)現(xiàn)按照特定功能對(duì)線程進(jìn)行集中式分組管理。用戶創(chuàng)建的每個(gè)線程均屬于某線程組,這個(gè)線程組可以在線程創(chuàng)建時(shí)指定,也可以不指定線程組以使該線程處于默認(rèn)的線程組之中。但是,一旦線程加入某線程組,該線程就一直存在于該線程組中直至線程死亡,不能在中途改變線程所屬的線程組。

        當(dāng)Java的Application應(yīng)用程序運(yùn)行時(shí),JVM創(chuàng)建名稱為main的線程組。除非單獨(dú)指定,在該應(yīng)用程序中創(chuàng)建的線程均屬于main線程組。在main線程組中可以創(chuàng)建其它名稱的線程組并將其它線程加入到該線程組中,依此類推,構(gòu)成線程和線程組之間的樹型管理和繼承關(guān)系。與線程類似,可以針對(duì)線程組對(duì)象進(jìn)行線程組的調(diào)度、狀態(tài)管理以及優(yōu)先級(jí)設(shè)置等。在對(duì)線程組進(jìn)行管理過(guò)程中,加入到某線程組中的所有線程均被看作統(tǒng)一的對(duì)象。

        6 小結(jié)

        Java語(yǔ)言對(duì)應(yīng)用程序多線程能力的支持增強(qiáng)了Java作為網(wǎng)絡(luò)程序設(shè)計(jì)語(yǔ)言的優(yōu)勢(shì),為實(shí)現(xiàn)分布式應(yīng)用系統(tǒng)中多客戶端的并發(fā)訪問(wèn)以及提高服務(wù)器的響應(yīng)效率奠定堅(jiān)實(shí)基礎(chǔ)。

        參考文獻(xiàn):

        [1] 陳強(qiáng), 孫建華, 等.Java程序設(shè)計(jì)[M].北京:人民郵電出版社,2001.12:125-137.

        [2] (美)布雷恩·奧弗蘭,邁克爾·莫里森 著;劉偉,朱詩(shī)兵, 等譯. Java2精要.語(yǔ)言詳解與編程指南[M].北京:清華大學(xué)出版社,2002.9.

        欧洲美熟女乱又伦av影片| 国产成人亚洲精品无码h在线| 99久久精品免费看国产情侣| 中文字幕av无码一区二区三区电影| 国产一区二区三区在线观看黄| 亚洲岛国一区二区三区| 少妇被又大又粗又爽毛片| 免费人成视频在线观看网站| 成人日韩av不卡在线观看| 自拍情爱视频在线观看| 日本丰满老妇bbw| 日韩精品无码免费专区网站| 国产天堂在线观看| 白白色发布永久免费观看视频| 亚洲综合在线一区二区三区| 巨爆中文字幕巨爆区爆乳| 亚洲精品第一国产综合亚av| 国内精品人妻无码久久久影院94 | 亚洲综合欧美在线一区在线播放| 国产精品黄在线观看免费软件| 精品九九视频| 国产精品亚洲一区二区三区久久| 亚洲av色影在线| 台湾佬综合网| 日日噜噜噜夜夜爽爽狠狠视频| 在线日本国产成人免费精品| 把女的下面扒开添视频| 国产精品密播放国产免费看| 天堂av在线一区二区| 亚洲精品中文字幕一区二区| 国产精品制服| 久热香蕉av在线爽青青| 国产又黄又湿又爽的免费视频| 免费在线观看av不卡网站 | 久久久老熟女一区二区三区 | 日日摸夜夜添夜夜添高潮喷水| 午夜成人理论无码电影在线播放| 美女爽好多水快进来视频| 亚洲一区二区三区色偷偷 | 亚洲熟妇AV一区二区三区宅男| 高清一级淫片a级中文字幕|