日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java--多线程编程

發(fā)布時間:2024/8/26 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java--多线程编程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java 多線程編程

Java給多線程編程提供了內(nèi)置的支持。一個多線程程序包含兩個或多個能并發(fā)運(yùn)行的部分。程序的每一部分都稱作一個線程,并且每個線程定義了一個獨(dú)立的執(zhí)行路徑。

多線程是多任務(wù)的一種特別的形式。多線程比多任務(wù)需要更小的開銷。

這里定義和線程相關(guān)的另一個術(shù)語:進(jìn)程:一個進(jìn)程包括由操作系統(tǒng)分配的內(nèi)存空間,包含一個或多個線程。一個線程不能獨(dú)立的存在,它必須是進(jìn)程的一部分。一個進(jìn)程一直運(yùn)行,直到所有的非守候線程都結(jié)束運(yùn)行后才能結(jié)束。

多線程能滿足程序員編寫非常有效率的程序來達(dá)到充分利用CPU的目的,因?yàn)镃PU的空閑時間能夠保持在最低限度。


一個線程的生命周

線程經(jīng)過其生命周期的各個階段。下圖顯示了一個線程完整的生命周期。

?

  • 新建狀態(tài):?一個新產(chǎn)生的線程從新狀態(tài)開始了它的生命周期。它保持這個狀態(tài)直到程序start這個線程。

  • 運(yùn)行狀態(tài):當(dāng)一個新狀態(tài)的線程被start以后,線程就變成可運(yùn)行狀態(tài),一個線程在此狀態(tài)下被認(rèn)為是開始執(zhí)行其任務(wù)

  • 就緒狀態(tài):當(dāng)一個線程等待另外一個線程執(zhí)行一個任務(wù)的時候,該線程就進(jìn)入就緒狀態(tài)。當(dāng)另一個線程給就緒狀態(tài)的線程發(fā)送信號時,該線程才重新切換到運(yùn)行狀態(tài)。

  • 休眠狀態(tài):?由于一個線程的時間片用完了,該線程從運(yùn)行狀態(tài)進(jìn)入休眠狀態(tài)。當(dāng)時間間隔到期或者等待的事件發(fā)生了,該狀態(tài)的線程切換到運(yùn)行狀態(tài)。

  • 終止?fàn)顟B(tài):?一個運(yùn)行狀態(tài)的線程完成任務(wù)或者其他終止條件發(fā)生,該線程就切換到終止?fàn)顟B(tài)。


線程的優(yōu)先級

每一個Java線程都有一個優(yōu)先級,這樣有助于操作系統(tǒng)確定線程的調(diào)度順序。Java優(yōu)先級在MIN_PRIORITY(1)和MAX_PRIORITY(10)之間的范圍內(nèi)。默認(rèn)情況下,每一個線程都會分配一個優(yōu)先級NORM_PRIORITY(5)。

具有較高優(yōu)先級的線程對程序更重要,并且應(yīng)該在低優(yōu)先級的線程之前分配處理器時間。然而,線程優(yōu)先級不能保證線程執(zhí)行的順序,而且非常依賴于平臺。


創(chuàng)建一個線程

Java提供了兩種創(chuàng)建線程方法:

  • 通過實(shí)現(xiàn)Runnable接口;

  • 通過繼承Thread類本身。


通過實(shí)現(xiàn)Runnable接口來創(chuàng)建線程

創(chuàng)建一個線程,最簡單的方法是創(chuàng)建一個實(shí)現(xiàn)Runnable接口的類。

為了實(shí)現(xiàn)Runnable,一個類只需要執(zhí)行一個方法調(diào)用run(),聲明如下:

?

public void?run()

?

?

你可以重寫該方法,重要的是理解的run()可以調(diào)用其他方法,使用其他類,并聲明變量,就像主線程一樣。

在創(chuàng)建一個實(shí)現(xiàn)Runnable接口的類之后,你可以在類中實(shí)例化一個線程對象。

Thread定義了幾個構(gòu)造方法,下面的這個是我們經(jīng)常使用的:

Thread(Runnable?threadOb,String?threadName);

?

這里,threadOb 是一個實(shí)現(xiàn)Runnable 接口的類的實(shí)例,并且 threadName指定新線程的名字。

新線程創(chuàng)建之后,你調(diào)用它的start()方法它才會運(yùn)行。

void?start();

?

實(shí)例

下面是一個創(chuàng)建線程并開始讓它執(zhí)行的實(shí)例:

//?創(chuàng)建一個新的線程 class?NewThread?implements?Runnable?{Thread?t;NewThread()?{//?創(chuàng)建第二個新線程t?=?new?Thread(this,?"Demo?Thread");System.out.println("Child?thread:?"?+?t);t.start();?//?開始線程}//?第二個線程入口public?void?run()?{try?{for(int?i?=?5;?i?>?0;?i--)?{System.out.println("Child?Thread:?"?+?i);//?暫停線程Thread.sleep(50);}}?catch?(InterruptedException?e)?{System.out.println("Child?interrupted.");}System.out.println("Exiting?child?thread.");} }public?class?ThreadDemo?{public?static?void?main(String?args[])?{new?NewThread();?//?創(chuàng)建一個新線程try?{for(int?i?=?5;?i?>?0;?i--)?{System.out.println("Main?Thread:?"?+?i);Thread.sleep(100);}}?catch?(InterruptedException?e)?{System.out.println("Main?thread?interrupted.");}System.out.println("Main?thread?exiting.");} }

?

編譯以上程序運(yùn)行結(jié)果如下:

Child?thread:?Thread[Demo?Thread,5,main] Main?Thread:?5 Child?Thread:?5 Child?Thread:?4 Main?Thread:?4 Child?Thread:?3 Child?Thread:?2 Main?Thread:?3 Child?Thread:?1 Exiting?child?thread. Main?Thread:?2 Main?Thread:?1 Main?thread?exiting.

?


通過繼承Thread來創(chuàng)建線程

創(chuàng)建一個線程的第二種方法是創(chuàng)建一個新的類,該類繼承Thread類,然后創(chuàng)建一個該類的實(shí)例。

繼承類必須重寫run()方法,該方法是新線程的入口點(diǎn)。它也必須調(diào)用start()方法才能執(zhí)行。

實(shí)例

//?通過繼承?Thread?創(chuàng)建線程 class?NewThread?extends?Thread?{NewThread()?{//?創(chuàng)建第二個新線程super("Demo?Thread");System.out.println("Child?thread:?"?+?this);start();?//?開始線程}//?第二個線程入口public?void?run()?{try?{for(int?i?=?5;?i?>?0;?i--)?{System.out.println("Child?Thread:?"?+?i);//?讓線程休眠一會Thread.sleep(50);}}?catch?(InterruptedException?e)?{System.out.println("Child?interrupted.");}System.out.println("Exiting?child?thread.");} }public?class?ExtendThread?{public?static?void?main(String?args[])?{new?NewThread();?//?創(chuàng)建一個新線程try?{for(int?i?=?5;?i?>?0;?i--)?{System.out.println("Main?Thread:?"?+?i);Thread.sleep(100);}}?catch?(InterruptedException?e)?{System.out.println("Main?thread?interrupted.");}System.out.println("Main?thread?exiting.");} }

?

編譯以上程序運(yùn)行結(jié)果如下:

Child?thread:?Thread[Demo?Thread,5,main] Main?Thread:?5 Child?Thread:?5 Child?Thread:?4 Main?Thread:?4 Child?Thread:?3 Child?Thread:?2 Main?Thread:?3 Child?Thread:?1 Exiting?child?thread. Main?Thread:?2 Main?Thread:?1 Main?thread?exiting.

Thread 方法

下表列出了Thread類的一些重要方法:

序號方法描述
1public void start()
使該線程開始執(zhí)行;Java?虛擬機(jī)調(diào)用該線程的?run?方法。
2public void run()
如果該線程是使用獨(dú)立的?Runnable?運(yùn)行對象構(gòu)造的,則調(diào)用該?Runnable?對象的?run?方法;否則,該方法不執(zhí)行任何操作并返回。
3public final void setName(String name)
改變線程名稱,使之與參數(shù)?name?相同。
4public final void setPriority(int priority)
?更改線程的優(yōu)先級。
5public final void setDaemon(boolean on)
將該線程標(biāo)記為守護(hù)線程或用戶線程。
6public final void join(long millisec)
等待該線程終止的時間最長為?millis?毫秒。
7public void interrupt()
中斷線程。
8public final boolean isAlive()
測試線程是否處于活動狀態(tài)。

測試線程是否處于活動狀態(tài)。 上述方法是被Thread對象調(diào)用的。下面的方法是Thread類的靜態(tài)方法。

序號方法描述
1public static void yield()
暫停當(dāng)前正在執(zhí)行的線程對象,并執(zhí)行其他線程。
2public static void sleep(long millisec)
在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計(jì)時器和調(diào)度程序精度和準(zhǔn)確性的影響。
3public static boolean holdsLock(Object x)
當(dāng)且僅當(dāng)當(dāng)前線程在指定的對象上保持監(jiān)視器鎖時,才返回?true。
4public static Thread currentThread()
返回對當(dāng)前正在執(zhí)行的線程對象的引用。
5public static void dumpStack()
將當(dāng)前線程的堆棧跟蹤打印至標(biāo)準(zhǔn)錯誤流。

實(shí)例

如下的ThreadClassDemo 程序演示了Thread類的一些方法:

//?文件名?:?DisplayMessage.java //?通過實(shí)現(xiàn)?Runnable?接口創(chuàng)建線程 public?class?DisplayMessage?implements?Runnable {private?String?message;public?DisplayMessage(String?message){this.message?=?message;}public?void?run(){while(true){System.out.println(message);}} }

?

//?文件名?:?GuessANumber.java //?通過繼承?Thread?類創(chuàng)建線程public?class?GuessANumber?extends?Thread {private?int?number;public?GuessANumber(int?number){this.number?=?number;}public?void?run(){int?counter?=?0;int?guess?=?0;do{guess?=?(int)?(Math.random()?*?100?+?1);System.out.println(this.getName()+?"?guesses?"?+?guess);counter++;}while(guess?!=?number);System.out.println("**?Correct!?"?+?this.getName()+?"?in?"?+?counter?+?"?guesses.**");} }

?

//?文件名?:?ThreadClassDemo.java public?class?ThreadClassDemo {public?static?void?main(String?[]?args){Runnable?hello?=?new?DisplayMessage("Hello");Thread?thread1?=?new?Thread(hello);thread1.setDaemon(true);thread1.setName("hello");System.out.println("Starting?hello?thread...");thread1.start();Runnable?bye?=?new?DisplayMessage("Goodbye");Thread?thread2?=?new?Thread(bye);thread2.setPriority(Thread.MIN_PRIORITY);thread2.setDaemon(true);System.out.println("Starting?goodbye?thread...");thread2.start();System.out.println("Starting?thread3...");Thread?thread3?=?new?GuessANumber(27);thread3.start();try{thread3.join();}catch(InterruptedException?e){System.out.println("Thread?interrupted.");}System.out.println("Starting?thread4...");Thread?thread4?=?new?GuessANumber(75);thread4.start();System.out.println("main()?is?ending...");} }

?

運(yùn)行結(jié)果如下,每一次運(yùn)行的結(jié)果都不一樣。

Starting?hello?thread... Starting?goodbye?thread... Hello Hello Hello Hello Hello Hello Hello Hello Hello Starting thread3... Hello Hello Starting?thread4... Hello Hello main() is ending...

?

線程的幾個主要概念:

在多線程編程時,你需要了解以下幾個概念:

  • 線程同步

  • 線程間通信

  • 線程死鎖

  • 線程控制:掛起、停止和恢復(fù)


多線程的使用

有效利用多線程的關(guān)鍵是理解程序是并發(fā)執(zhí)行而不是串行執(zhí)行的。例如:程序中有兩個子系統(tǒng)需要并發(fā)執(zhí)行,這時候就需要利用多線程編程。

通過對多線程的使用,可以編寫出非常高效的程序。不過請注意,如果你創(chuàng)建太多的線程,程序執(zhí)行的效率實(shí)際上是降低了,而不是提升了。

請記住,上下文的切換開銷也很重要,如果你創(chuàng)建了太多的線程,CPU花費(fèi)在上下文的切換的時間將多于執(zhí)行程序的時間!

轉(zhuǎn)載于:https://www.cnblogs.com/DreamRecorder/p/9228645.html

總結(jié)

以上是生活随笔為你收集整理的Java--多线程编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。