java中實現(xiàn)多線程代碼 java實現(xiàn)多線程方法

java 多線程有幾種實現(xiàn)方法

1、繼承Thread類實現(xiàn)多線程

創(chuàng)新互聯(lián)服務(wù)項目包括漢南網(wǎng)站建設(shè)、漢南網(wǎng)站制作、漢南網(wǎng)頁制作以及漢南網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,漢南網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到漢南省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

繼承Thread類的方法盡管被我列為一種多線程實現(xiàn)方式,但Thread本質(zhì)上也是實現(xiàn)了Runnable接口的一個實例,它代表一個線程的實例,并且,啟動線程的唯一方法就是通過Thread類的start()實例方法。start()方法是一個native方法,它將啟動一個新線程,并執(zhí)行run()方法。這種方式實現(xiàn)多線程很簡單,通過自己的類直接extend Thread,并復(fù)寫run()方法,就可以啟動新線程并執(zhí)行自己定義的run()方法。例如:

[java] view plain copy

public class MyThread extends Thread {

public void run() {

System.out.println("MyThread.run()");

}

}

在合適的地方啟動線程如下:

[java] view plain copy

MyThread myThread1 = new MyThread();

MyThread myThread2 = new MyThread();

myThread1.start();

myThread2.start();

2、實現(xiàn)Runnable接口方式實現(xiàn)多線程

如果自己的類已經(jīng)extends另一個類,就無法直接extends Thread,此時,必須實現(xiàn)一個Runnable接口,如下:

[java] view plain copy

public class MyThread extends OtherClass implements Runnable {

public void run() {

System.out.println("MyThread.run()");

}

}

為了啟動MyThread,需要首先實例化一個Thread,并傳入自己的MyThread實例:

[java] view plain copy

MyThread myThread = new MyThread();

Thread thread = new Thread(myThread);

thread.start();

事實上,當(dāng)傳入一個Runnable target參數(shù)給Thread后,Thread的run()方法就會調(diào)用target.run(),參考JDK源代碼:

[java] view plain copy

public void run() {

if (target != null) {

target.run();

}

}

3、使用ExecutorService、Callable、Future實現(xiàn)有返回結(jié)果的多線程

ExecutorService、Callable、Future這個對象實際上都是屬于Executor框架中的功能類。想要詳細了解Executor框架的可以訪問 ,這里面對該框架做了很詳細的解釋。返回結(jié)果的線程是在JDK1.5中引入的新特征,確實很實用,有了這種特征我就不需要再為了得到返回值而大費周折了,而且即便實現(xiàn)了也可能漏洞百出。

可返回值的任務(wù)必須實現(xiàn)Callable接口,類似的,無返回值的任務(wù)必須Runnable接口。執(zhí)行Callable任務(wù)后,可以獲取一個Future的對象,在該對象上調(diào)用get就可以獲取到Callable任務(wù)返回的Object了,再結(jié)合線程池接口ExecutorService就可以實現(xiàn)傳說中有返回結(jié)果的多線程了。下面提供了一個完整的有返回結(jié)果的多線程測試例子,在JDK1.5下驗證過沒問題可以直接使用。

Java多線程程序設(shè)計初步入門

在Java語言產(chǎn)生前 傳統(tǒng)的程序設(shè)計語言的程序同一時刻只能單任務(wù)操作 效率非常低 例如程序往往在接收數(shù)據(jù)輸入時發(fā)生阻塞 只有等到程序獲得數(shù)據(jù)后才能繼續(xù)運行 隨著Internet的迅猛發(fā)展 這種狀況越來越不能讓人們?nèi)淌?如果網(wǎng)絡(luò)接收數(shù)據(jù)阻塞 后臺程序就處于等待狀態(tài)而不繼續(xù)任何操作 而這種阻塞是經(jīng)常會碰到的 此時CPU資源被白白的閑置起來 如果在后臺程序中能夠同時處理多個任務(wù) 該多好?。?yīng)Internet技術(shù)而生的Java語言解決了這個問題 多線程程序是Java語言的一個很重要的特點 在一個Java程序中 我們可以同時并行運行多個相對獨立的線程 例如 我們?nèi)绻麆?chuàng)建一個線程來進行數(shù)據(jù)輸入輸出 而創(chuàng)建另一個線程在后臺進行其它的數(shù)據(jù)處理 如果輸入輸出線程在接收數(shù)據(jù)時阻塞 而處理數(shù)據(jù)的線程仍然在運行 多線程程序設(shè)計大大提高了程序執(zhí)行效率和處理能力

線程的創(chuàng)建

我們知道Java是面向?qū)ο蟮某绦蛘Z言 用Java進行程序設(shè)計就是設(shè)計和使用類 Java為我們提供了線程類Thread來創(chuàng)建線程 創(chuàng)建線程與創(chuàng)建普通的類的對象的操作是一樣的 而線程就是Thread類或其子類的實例對象 下面是一個創(chuàng)建啟動一個線程的語句

Thread thread =new Thread(); file://聲明一個對象實例 即創(chuàng)建一個線程

Thread run(); file://用Thread類中的run()方法啟動線程

從這個例子 我們可以通過Thread()構(gòu)造方法創(chuàng)建一個線程 并啟動該線程 事實上 啟動線程 也就是啟動線程的run()方法 而Thread類中的run()方法沒有任何操作語句 所以這個線程沒有任何操作 要使線程實現(xiàn)預(yù)定功能 必須定義自己的run()方法 Java中通常有兩種方式定義run()方法

通過定義一個Thread類的子類 在該子類中重寫run()方法 Thread子類的實例對象就是一個線程 顯然 該線程有我們自己設(shè)計的線程體run()方法 啟動線程就啟動了子類中重寫的run()方法

通過Runnable接口 在該接口中定義run()方法的接口 所謂接口跟類非常類似 主要用來實現(xiàn)特殊功能 如復(fù)雜關(guān)系的多重繼承功能 在此 我們定義一個實現(xiàn)Runnable() 接口的類 在該類中定義自己的run()方法 然后以該類的實例對象為參數(shù)調(diào)用Thread類的構(gòu)造方法來創(chuàng)建一個線程

線程被實際創(chuàng)建后處于待命狀態(tài) 激活(啟動)線程就是啟動線程的run()方法 這是通過調(diào)用線程的start()方法來實現(xiàn)的

下面一個例子實踐了如何通過上述兩種方法創(chuàng)建線程并啟動它們

// 通過Thread類的子類創(chuàng)建的線程   class thread extends Thread { file://自定義線程的run()方法   public void run() {   System out println( Thread is running… ); }   }   file://通過Runnable接口創(chuàng)建的另外一個線程 class thread implements Runnable   { file://自定義線程的run()方法 public void run() {   System out println( Thread is running… ); }   }   file://程序的主類   class Multi_Thread file://聲明主類 {   plubic static void mail(String args[]) file://聲明主方法 {   thread threadone=new thread (); file://用Thread類的子類創(chuàng)建線程   Thread threado=new Thread(new thread ()); file://用Runnable接口類的對象創(chuàng)建線程   threadone start(); threado start(); 方法啟動線程 }   }

運行該程序就可以看出 線程threadone和threado交替占用CPU 處于并行運行狀態(tài) 可以看出 啟動線程的run()方法是通過調(diào)用線程的start()方法來實現(xiàn)的(見上例中主類) 調(diào)用start()方法啟動線程的run()方法不同于一般的調(diào)用方法 調(diào)用一般方法時 必須等到一般方法執(zhí)行完畢才能夠返回start()方法 而啟動線程的run()方法后 start()告訴系統(tǒng)該線程準(zhǔn)備就緒可以啟動run()方法后 就返回start()方法執(zhí)行調(diào)用start()方法語句下面的語句 這時run()方法可能還在運行 這樣 線程的啟動和運行并行進行 實現(xiàn)了多任務(wù)操作

線程的優(yōu)先級

對于多線程程序 每個線程的重要程度是不盡相同 如多個線程在等待獲得CPU時間時 往往我們需要優(yōu)先級高的線程優(yōu)先搶占到CPU時間得以執(zhí)行 又如多個線程交替執(zhí)行時 優(yōu)先級決定了級別高的線程得到CPU的次數(shù)多一些且時間多長一些 這樣 高優(yōu)先級的線程處理的任務(wù)效率就高一些

Java中線程的優(yōu)先級從低到高以整數(shù) ~ 表示 共分為 級 設(shè)置優(yōu)先級是通過調(diào)用線程對象的setPriority()方法 如上例中 設(shè)置優(yōu)先級的語句為

thread threadone=new thread (); file://用Thread類的子類創(chuàng)建線程

Thread threado=new Thread(new thread ()); file://用Runnable接口類的對象創(chuàng)建線程

threadone setPriority( ); file://設(shè)置threadone的優(yōu)先級

threado setPriority( ); file://設(shè)置threado的優(yōu)先級

threadone start(); threado start(); 方法啟動線程

這樣 線程threadone將會優(yōu)先于線程threado執(zhí)行 并將占有更多的CPU時間 該例中 優(yōu)先級設(shè)置放在線程啟動前 也可以在啟動后進行設(shè)置 以滿足不同的優(yōu)先級需求

線程的(同步)控制

一個Java程序的多線程之間可以共享數(shù)據(jù) 當(dāng)線程以異步方式訪問共享數(shù)據(jù)時 有時候是不安全的或者不和邏輯的 比如 同一時刻一個線程在讀取數(shù)據(jù) 另外一個線程在處理數(shù)據(jù) 當(dāng)處理數(shù)據(jù)的線程沒有等到讀取數(shù)據(jù)的線程讀取完畢就去處理數(shù)據(jù) 必然得到錯誤的處理結(jié)果 這和我們前面提到的讀取數(shù)據(jù)和處理數(shù)據(jù)并行多任務(wù)并不矛盾 這兒指的是處理數(shù)據(jù)的線程不能處理當(dāng)前還沒有讀取結(jié)束的數(shù)據(jù) 但是可以處理其它的數(shù)據(jù)

如果我們采用多線程同步控制機制 等到第一個線程讀取完數(shù)據(jù) 第二個線程才能處理該數(shù)據(jù) 就會避免錯誤 可見 線程同步是多線程編程的一個相當(dāng)重要的技術(shù)

在講線程的同步控制前我們需要交代如下概念

用Java關(guān)鍵字synchonized同步對共享數(shù)據(jù)操作的方法

在一個對象中 用synchonized聲明的方法為同步方法 Java中有一個同步模型 監(jiān)視器 負責(zé)管理線程對對象中的同步方法的訪問 它的原理是 賦予該對象唯一一把 鑰匙 當(dāng)多個線程進入對象 只有取得該對象鑰匙的線程才可以訪問同步方法 其它線程在該對象中等待 直到該線程用wait()方法放棄這把鑰匙 其它等待的線程搶占該鑰匙 搶占到鑰匙的線程后才可得以執(zhí)行 而沒有取得鑰匙的線程仍被阻塞在該對象中等待

file://聲明同步的一種方式 將方法聲明同步

class store  {public synchonized void store_in(){… }public synchonized void store_out(){  … }}

利用wait() notify()及notifyAll()方法發(fā)送消息實現(xiàn)線程間的相互聯(lián)系

Java程序中多個線程通過消息來實現(xiàn)互動聯(lián)系的 這幾種方法實現(xiàn)了線程間的消息發(fā)送 例如定義一個對象的synchonized 方法 同一時刻只能夠有一個線程訪問該對象中的同步方法 其它線程被阻塞 通??梢杂胣otify()或notifyAll()方法喚醒其它一個或所有線程 而使用wait()方法來使該線程處于阻塞狀態(tài) 等待其它的線程用notify()喚醒

一個實際的例子就是生產(chǎn)和銷售 生產(chǎn)單元將產(chǎn)品生產(chǎn)出來放在倉庫中 銷售單元則從倉庫中提走產(chǎn)品 在這個過程中 銷售單元必須在倉庫中有產(chǎn)品時才能提貨 如果倉庫中沒有產(chǎn)品 則銷售單元必須等待

程序中 假如我們定義一個倉庫類store 該類的實例對象就相當(dāng)于倉庫 在store類中定義兩個成員方法 store_in() 用來模擬產(chǎn)品制造者往倉庫中添加產(chǎn)品 strore_out()方法則用來模擬銷售者從倉庫中取走產(chǎn)品 然后定義兩個線程類 customer類 其中的run()方法通過調(diào)用倉庫類中的store_out()從倉庫中取走產(chǎn)品 模擬銷售者 另外一個線程類producer中的run()方法通過調(diào)用倉庫類中的store_in()方法向倉庫添加產(chǎn)品 模擬產(chǎn)品制造者 在主類中創(chuàng)建并啟動線程 實現(xiàn)向倉庫中添加產(chǎn)品或取走產(chǎn)品

如果倉庫類中的store_in() 和store_out()方法不聲明同步 這就是個一般的多線程 我們知道 一個程序中的多線程是交替執(zhí)行的 運行也是無序的 這樣 就可能存在這樣的問題

倉庫中沒有產(chǎn)品了 銷售者還在不斷光顧 而且還不停的在 取 產(chǎn)品 這在現(xiàn)實中是不可思義的 在程序中就表現(xiàn)為負值 如果將倉庫類中的stroe_in()和store_out()方法聲明同步 如上例所示 就控制了同一時刻只能有一個線程訪問倉庫對象中的同步方法 即一個生產(chǎn)類線程訪問被聲明為同步的store_in()方法時 其它線程將不能夠訪問對象中的store_out()同步方法 當(dāng)然也不能訪問store_in()方法 必須等到該線程調(diào)用wait()方法放棄鑰匙 其它線程才有機會訪問同步方法

lishixinzhi/Article/program/Java/gj/201311/27301

編寫一個多線程的java 程序

public class RunThread implements Runnable{

String name;

Thread runner;

static boolean bool=true;

public RunThread(String threadName) {

name=threadName;

}

public void onStart()

{

runner = new Thread(this);

runner.setName(name);

runner.start();

}

public void run() {

String name=Thread.currentThread().getName();

System.out.println(name + " 線程運行開始!");

int index=0;

if(name.equals("小寫字母"))

index='a';

else if(name.equals("大寫字母"))

index='A';

while(!bool);

bool=false;

for(int i=index;i26+index;i++)

System.out.print((char)i+" ");

System.out.println();

bool=true;

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(name + " 線程運行結(jié)束!");

}

public static void main(String[] args) {

RunThread a=new RunThread("小寫字母");

RunThread b=new RunThread("大寫字母");

a.onStart();

b.onStart();

//System.out.println(" 線程運行開始!");

}

在Java 中多線程的實現(xiàn)方法有哪些,如何使用~~~~~~~~~~~~~~~~~~急

1、 認識Thread和Runnable

Java中實現(xiàn)多線程有兩種途徑:繼承Thread類或者實現(xiàn)Runnable接口。Runnable是接口,建議用接口的方式生成線程,因為接口可以實現(xiàn)多繼承,況且Runnable只有一個run方法,很適合繼承。在使用Thread的時候只需繼承Thread,并且new一個實例出來,調(diào)用start()方法即可以啟動一個線程。

Thread Test = new Thread();

Test.start();

在使用Runnable的時候需要先new一個實現(xiàn)Runnable的實例,之后啟動Thread即可。

Test impelements Runnable;

Test t = new Test();

Thread test = new Thread(t);

test.start();

總結(jié):Thread和Runnable是實現(xiàn)java多線程的2種方式,runable是接口,thread是類,建議使用runable實現(xiàn)java多線程,不管如何,最終都需要通過thread.start()來使線程處于可運行狀態(tài)。

2、 認識Thread的start和run

1) start:

用start方法來啟動線程,真正實現(xiàn)了多線程運行,這時無需等待run方法體代碼執(zhí)行完畢而直接繼續(xù)執(zhí)行下面的代碼。通過調(diào)用Thread類的start()方法來啟動一個線程,這時此線程處于就緒(可運行)狀態(tài),并沒有運行,一旦得到spu時間片,就開始執(zhí)行run()方法,這里方法run()稱為線程體,它包含了要執(zhí)行的這個線程的內(nèi)容,Run方法運行結(jié)束,此線程隨即終止。

2) run:

run()方法只是類的一個普通方法而已,如果直接調(diào)用Run方法,程序中依然只有主線程這一個線程,其程序執(zhí)行路徑還是只有一條,還是要順序執(zhí)行,還是要等待run方法體執(zhí)行完畢后才可繼續(xù)執(zhí)行下面的代碼,這樣就沒有達到寫線程的目的。

總結(jié):調(diào)用start方法方可啟動線程,而run方法只是thread的一個普通方法調(diào)用,還是在主線程里執(zhí)行。

3、 線程狀態(tài)說明

線程狀態(tài)從大的方面來說,可歸結(jié)為:初始狀態(tài)、可運行狀態(tài)、不可運行狀態(tài)和消亡狀態(tài),具體可細分為上圖所示7個狀態(tài),說明如下:

1) 線程的實現(xiàn)有兩種方式,一是繼承Thread類,二是實現(xiàn)Runnable接口,但不管怎樣,當(dāng)我們new了thread實例后,線程就進入了初始狀態(tài);

2) 當(dāng)該對象調(diào)用了start()方法,就進入可運行狀態(tài);

3) 進入可運行狀態(tài)后,當(dāng)該對象被操作系統(tǒng)選中,獲得CPU時間片就會進入運行狀態(tài);

4) 進入運行狀態(tài)后case就比較多,大致有如下情形:

·run()方法或main()方法結(jié)束后,線程就進入終止?fàn)顟B(tài);

·當(dāng)線程調(diào)用了自身的sleep()方法或其他線程的join()方法,就會進入阻塞狀態(tài)(該狀態(tài)既停止當(dāng)前線程,但并不釋放所占有的資源)。當(dāng)sleep()結(jié)束或join()結(jié)束后,該線程進入可運行狀態(tài),繼續(xù)等待OS分配時間片;

·當(dāng)線程剛進入可運行狀態(tài)(注意,還沒運行),發(fā)現(xiàn)將要調(diào)用的資源被鎖牢(synchroniza,lock),將會立即進入鎖池狀態(tài),等待獲取鎖標(biāo)記(這時的鎖池里也許已經(jīng)有了其他線程在等待獲取鎖標(biāo)記,這時它們處于隊列狀態(tài),既先到先得),一旦線程獲得鎖標(biāo)記后,就轉(zhuǎn)入可運行狀態(tài),等待OS分配CPU時間片;

·當(dāng)線程調(diào)用wait()方法后會進入等待隊列(進入這個狀態(tài)會釋放所占有的所有資源,與阻塞狀態(tài)不同),進入這個狀態(tài)后,是不能自動喚醒的,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒(由于notify()只是喚醒一個線程,但我們由不能確定具體喚醒的是哪一個線程,也許我們需要喚醒的線程不能夠被喚醒,因此在實際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒后會進入鎖池,等待獲取鎖標(biāo)記。

·當(dāng)線程調(diào)用stop方法,即可使線程進入消亡狀態(tài),但是由于stop方法是不安全的,不鼓勵使用,大家可以通過run方法里的條件變通實現(xiàn)線程的stop。

分享標(biāo)題:java中實現(xiàn)多線程代碼 java實現(xiàn)多線程方法
當(dāng)前地址:http://muchs.cn/article20/ddccico.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google靜態(tài)網(wǎng)站、網(wǎng)站制作、搜索引擎優(yōu)化、微信小程序、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)