国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

Java多線程

2019-11-06 07:38:58
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

java 多線程

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

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

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

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

一個(gè)線程的生命周

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

新?tīng)顟B(tài): 一個(gè)新產(chǎn)生的線程從新?tīng)顟B(tài)開(kāi)始了它的生命周期。它保持這個(gè)狀態(tài)直到程序start這個(gè)線程。

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

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

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

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

線程的優(yōu)先級(jí)

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

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

創(chuàng)建一個(gè)線程

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

通過(guò)實(shí)現(xiàn)Runable接口;

通過(guò)繼承Thread類本身。

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

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

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

Public void run()

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

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

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

Thread(Runnable threadOb,String threadName);

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

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

void start();

實(shí)例

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

// 創(chuàng)建一個(gè)新的線程class NewThread implements Runnable {   Thread t;   NewThread() {      // 創(chuàng)建第二個(gè)新線程      t = new Thread(this, "Demo Thread");      System.out.println("Child thread: " + t);      t.start(); // 開(kāi)始線程   }     // 第二個(gè)線程入口   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)建一個(gè)新線程      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: 5Child Thread: 5Child Thread: 4Main Thread: 4Child Thread: 3Child Thread: 2Main Thread: 3Child Thread: 1Exiting child thread.Main Thread: 2Main Thread: 1Main thread exiting.

通過(guò)繼承Thread來(lái)創(chuàng)建線程

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

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

實(shí)例

// 通過(guò)繼承 Thread 創(chuàng)建線程class NewThread extends Thread {   NewThread() {      // 創(chuàng)建第二個(gè)新線程      super("Demo Thread");      System.out.println("Child thread: " + this);      start(); // 開(kāi)始線程   }    // 第二個(gè)線程入口   public void run() {      try {         for(int i = 5; i > 0; i--) {            System.out.println("Child Thread: " + i);                            // 讓線程休眠一會(huì)            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)建一個(gè)新線程      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: 5Child Thread: 5Child Thread: 4Main Thread: 4Child Thread: 3Child Thread: 2Main Thread: 3Child Thread: 1Exiting child thread.Main Thread: 2Main Thread: 1Main thread exiting.

 

Thread 方法

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

序號(hào)

方法描述

1

public void start()使該線程開(kāi)始執(zhí)行;Java 虛擬機(jī)調(diào)用該線程的 run 方法。

2

public void run()如果該線程是使用獨(dú)立的 Runnable 運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該 Runnable 對(duì)象的 run 方法;否則,該方法不執(zhí)行任何操作并返回。

3

public final void setName(String name)改變線程名稱,使之與參數(shù) name 相同。

4

public final void setPriority(int priority)更改線程的優(yōu)先級(jí)。

5

public final void setDaemon(boolean on)將該線程標(biāo)記為守護(hù)線程或用戶線程。

6

public final void join(long millisec)等待該線程終止的時(shí)間最長(zhǎng)為 millis 毫秒。

7

public void interrupt()中斷線程。

8

public final boolean isAlive()測(cè)試線程是否處于活動(dòng)狀態(tài)。

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

序號(hào)

方法描述

1

public static void yield()暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程。

2

public static void sleep(long millisec)在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行),此操作受到系統(tǒng)計(jì)時(shí)器和調(diào)度程序精度和準(zhǔn)確性的影響。

3

public static boolean holdsLock(Object x)當(dāng)且僅當(dāng)當(dāng)前線程在指定的對(duì)象上保持監(jiān)視器鎖時(shí),才返回 true。

4

public static Thread currentThread()返回對(duì)當(dāng)前正在執(zhí)行的線程對(duì)象的引用。

5

public static void dumpStack()將當(dāng)前線程的堆棧跟蹤打印至標(biāo)準(zhǔn)錯(cuò)誤流。

實(shí)例

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

// 文件名 : DisplayMessage.java// 通過(guò)實(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// 通過(guò)繼承 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.javapublic 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(hello);      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...HelloHelloHelloHelloHelloHelloHelloHelloHelloThread-2 guesses 27Hello** Correct! Thread-2 in 102 guesses.**HelloStarting thread4...HelloHello..........remaining result produced.

線程的幾個(gè)主要概念:

在多線程編程時(shí),你需要了解以下幾個(gè)概念:

線程同步

線程間通信

線程死鎖

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

多線程的使用

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

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

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


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 雷山县| 湖北省| 杨浦区| 白河县| 宝丰县| 泊头市| 金华市| 黔西县| 舒兰市| 环江| 郑州市| 天全县| 区。| 綦江县| 三原县| 灵川县| 临海市| 突泉县| 余庆县| 长丰县| 九寨沟县| 林州市| 泾源县| 塘沽区| 漳州市| 阳山县| 潞西市| 遵化市| 旬邑县| 旺苍县| 郸城县| 汝州市| 吴桥县| 象山县| 南投县| 姚安县| 如皋市| 项城市| 郧西县| 宁都县| 岑巩县|