欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多線程中線程的兩種創(chuàng)建方式及比較代碼示例

 更新時間:2017年11月28日 08:41:48   作者:muzeet  
這篇文章主要介紹了Java多線程中線程的兩種創(chuàng)建方式及比較代碼示例,簡單介紹了線程的概念,并行與并發(fā)等,然后通過實例代碼向大家展示了線程的創(chuàng)建,具有一定參考價值,需要的朋友可以了解下。

1.線程的概念:線程(thread)是指一個任務(wù)從頭至尾的執(zhí)行流,線程提供一個運(yùn)行任務(wù)的機(jī)制,對于java而言,一個程序中可以并發(fā)的執(zhí)行多個線程,這些線程可以在多處理器系統(tǒng)上同時運(yùn)行。當(dāng)程序作為一個應(yīng)用程序運(yùn)行時,java解釋器為main()方法啟動一個線程。

2.并行與并發(fā):

(1)并發(fā):在單處理器系統(tǒng)中,多個線程共享CPU時間,而操作系統(tǒng)負(fù)責(zé)調(diào)度及分配資源給它們。

(2)并行:在多處理器系統(tǒng)中,多個處理器可以同時運(yùn)行多個線程,這些線程在同一時間可以同時運(yùn)行,而不同于并發(fā),只能多個線程共享CPU時間,同一時間只能運(yùn)行一個線程。

3.線程的創(chuàng)建:

(1)基礎(chǔ)概念:java中每個任務(wù)就是一個可運(yùn)行對象,為了創(chuàng)建任務(wù),必須首先定義任務(wù)類,任務(wù)類必須實現(xiàn)Runnable接口。而線程本質(zhì)上講就是便于任務(wù)執(zhí)行的對象。一個線程的執(zhí)行過程就是一個任務(wù)類中run()方法的執(zhí)行到結(jié)束。

(2)通過Runnable接口創(chuàng)建線程:

  a.定義一個任務(wù)類實現(xiàn)Runnable接口,實現(xiàn)Runnable接口中的run()方法(run()方法告知系統(tǒng)線程該如何運(yùn)行),run()方法中定義具體的任務(wù)代碼或處理邏輯。

  b.定義了任務(wù)類后,為任務(wù)類創(chuàng)建一個任務(wù)對象。

  c.任務(wù)必須在線程中執(zhí)行,創(chuàng)建一個Tread類的對象,將前面創(chuàng)建的實現(xiàn)了Runnable接口的任務(wù)類對象作為參數(shù)傳遞給Tread類的構(gòu)造方法。

  d.調(diào)用Tread類對象的start()方法,啟動一個線程。它會導(dǎo)致任務(wù)的run()方法被執(zhí)行,當(dāng)run()方法執(zhí)行完畢,則線程就終止。

  實例代碼:

package com.muzeet.mutithread;

//每個任務(wù)都是Runable接口的一個實例,任務(wù)是可運(yùn)行對象,線程是便于任務(wù)執(zhí)行的對象。必須創(chuàng)建任務(wù)類,重寫run方法定義任務(wù)
public class ThreadDemo1 implements Runnable {
 private int countDown = 10;
 @Override
 //重寫run方法,定義任務(wù)
 public void run() {
  while(countDown-- >0)
  {
   System.out.println("$" + Thread.currentThread().getName() 
     + "(" + countDown + ")");
  }
 }
 //調(diào)用start方法會啟動一個線程,導(dǎo)致任務(wù)中的run方法被調(diào)用,run方法執(zhí)行完畢則線程終止
 
 public static void main(String[] args) {
  Runnable demo1 = new ThreadDemo1();
  
  Thread thread1 = new Thread(demo1);
  Thread thread2 = new Thread(demo1);
  thread1.start();
  thread2.start();
  
  System.out.println("火箭發(fā)射倒計時:");  
 }

}

程序運(yùn)行結(jié)果:

火箭發(fā)射倒計時:
$Thread-0(9)
$Thread-0(8)
$Thread-0(7)
$Thread-0(6)
$Thread-0(5)
$Thread-0(4)
$Thread-0(3)
$Thread-0(2)
$Thread-0(1)
$Thread-0(0)

同時運(yùn)行兩個任務(wù)對象:

public static void main(String[] args) {
  Runnable demo1 = new ThreadDemo1();
  Runnable demo2 = new ThreadDemo1();
  Thread thread1 = new Thread(demo1);
  Thread thread2 = new Thread(demo2);
  thread1.start();
  thread2.start();
  
  System.out.println("火箭發(fā)射倒計時:"); 
 }

 運(yùn)行結(jié)果:

火箭發(fā)射倒計時:
$Thread-0(9)
$Thread-0(8)
$Thread-0(7)
$Thread-0(6)
$Thread-1(9)
$Thread-0(5)
$Thread-1(8)
$Thread-0(4)
$Thread-1(7)
$Thread-0(3)
$Thread-1(6)
$Thread-1(5)
$Thread-0(2)
$Thread-1(4)
$Thread-1(3)
$Thread-1(2)
$Thread-1(1)
$Thread-1(0)
$Thread-0(1)
$Thread-0(0)

(3)繼承Thread類來創(chuàng)建線程: 

  a.首先創(chuàng)建一個任務(wù)類extends Thread類,因為Thread類實現(xiàn)了Runnable接口,所以自定義的任務(wù)類也實現(xiàn)了Runnable接口,重新run()方法,其中定義具體的任務(wù)代碼或處理邏輯。

  b.創(chuàng)建一個任務(wù)類對象,可以用Thread或者Runnable作為自定義的變量類型。

  c.調(diào)用自定義對象的start()方法,啟動一個線程。

  示例代碼:

package com.muzeet.mutithread;

//每個任務(wù)都是Runable接口的一個實例,任務(wù)是可運(yùn)行對象,線程即可運(yùn)行對象。必須創(chuàng)建任務(wù)類,重寫run方法定義任務(wù)
public class ExtendFromThread extends Thread {
 private int countDown = 10;
 @Override
 //重寫run方法,定義任務(wù)
 public void run() {
  while(countDown-- >0)
  {
   System.out.println("$" + this.getName() 
     + "(" + countDown + ")");
  }
 }
 //調(diào)用start方法會啟動一個線程,導(dǎo)致任務(wù)中的run方法被調(diào)用,run方法執(zhí)行完畢則線程終止
 
 public static void main(String[] args) {
  
  ExtendFromThread thread1 = new ExtendFromThread();
  ExtendFromThread thread2 = new ExtendFromThread();
  thread1.start();
  thread2.start();
  
  System.out.println("火箭發(fā)射倒計時:"); 
 }

}

運(yùn)行結(jié)果: 

火箭發(fā)射倒計時:
$Thread-0(9)
$Thread-0(8)
$Thread-0(7)
$Thread-0(6)
$Thread-0(5)
$Thread-0(4)
$Thread-0(3)
$Thread-0(2)
$Thread-0(1)
$Thread-0(0)
$Thread-1(9)
$Thread-1(8)
$Thread-1(7)
$Thread-1(6)
$Thread-1(5)
$Thread-1(4)
$Thread-1(3)
$Thread-1(2)
$Thread-1(1)
$Thread-1(0)

一個線程等待另一個線程結(jié)束后再執(zhí)行:當(dāng)執(zhí)行PrintNum這個任務(wù)時,打印到數(shù)字50時,轉(zhuǎn)而去執(zhí)行打印字符C這個任務(wù),知道線程thread4執(zhí)行完才繼續(xù)執(zhí)行打印數(shù)字任務(wù)。

package com.muzeet.testThread;

public class PrintNum implements Runnable {

 private int lastNum;
 
 public PrintNum(int n)
 {
  lastNum = n;
 }

 @Override
 public void run() {
  // TODO Auto-generated method stub
  Thread thread4 = new Thread(new PrintChar('c', 40));
  thread4.start();
  try {
  for(int i=1;i<=lastNum;i++)
  {
   System.out.println(" " + i);
   if(i == 50)
   {
  thread4.join();
    
   }
  }
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
}

4.兩種方法的比較(轉(zhuǎn)載)

首先分析兩種方式的輸出結(jié)果,同樣是創(chuàng)建了兩個線程,為什么結(jié)果不一樣呢?

使用實現(xiàn)Runnable接口方式創(chuàng)建線程可以共享同一個目標(biāo)對象(TreadDemo1tt=newTreadDemo1();),實現(xiàn)了多個相同線程處理同一份資源。當(dāng)?shù)谝粋€線程執(zhí)行完任務(wù)后,countDown已經(jīng)為0,所以第二個線程就不會輸出。而繼承Thread創(chuàng)建線程的方式,new出了兩個任務(wù)類對象,有各自的成員變量,相互之間不干擾。

然后再看一段來自JDK的解釋:

Runnable接口應(yīng)該由那些打算通過某一線程執(zhí)行其實例的類來實現(xiàn)。類必須定義一個稱為run的無參數(shù)方法。

設(shè)計該接口的目的是為希望在活動時執(zhí)行代碼的對象提供一個公共協(xié)議。例如,Thread類實現(xiàn)了Runnable。激活的意思是說某個線程已啟動并且尚未停止。

此外,Runnable為非Thread子類的類提供了一種激活方式。通過實例化某個Thread實例并將自身作為運(yùn)行目標(biāo),就可以運(yùn)行實現(xiàn)Runnable的類。大多數(shù)情況下,如果只想重寫run()方法,而不重寫其他Thread方法,那么應(yīng)使用Runnable接口。這很重要,因為除非程序員打算修改或增強(qiáng)類的基本行為,否則不應(yīng)為該類創(chuàng)建子類。(推薦使用創(chuàng)建任務(wù)類,并實現(xiàn)Runnable接口,而不是繼承Thread類)

采用繼承Thread類方式:

(1)優(yōu)點:編寫簡單,如果需要訪問當(dāng)前線程,無需使用Thread.currentThread()方法,直接使用this,即可獲得當(dāng)前線程。

(2)缺點:因為線程類已經(jīng)繼承了Thread類,所以不能再繼承其他的父類。

采用實現(xiàn)Runnable接口方式:

(1)優(yōu)點:線程類只是實現(xiàn)了Runable接口,還可以繼承其他的類。在這種方式下,可以多個線程共享同一個目標(biāo)對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU代碼和數(shù)據(jù)分開,形成清晰的模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷搿?/p>

(2)缺點:編程稍微復(fù)雜,如果需要訪問當(dāng)前線程,必須使用Thread.currentThread()方法。

總結(jié)

以上就是本文關(guān)于Java多線程中線程的兩種創(chuàng)建方式及比較代碼示例的全部內(nèi)容,希望對大家有所幫助。如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關(guān)文章

  • SpringBoot在IDEA中實現(xiàn)熱部署的步驟

    SpringBoot在IDEA中實現(xiàn)熱部署的步驟

    這篇文章主要介紹了SpringBoot在IDEA中實現(xiàn)熱部署的步驟,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • RocketMQ中的消費(fèi)者啟動流程解讀

    RocketMQ中的消費(fèi)者啟動流程解讀

    這篇文章主要介紹了RocketMQ中的消費(fèi)者啟動流程解讀,RocketMQ是一款高性能、高可靠性的分布式消息中間件,消費(fèi)者是RocketMQ中的重要組成部分,消費(fèi)者負(fù)責(zé)從消息隊列中獲取消息并進(jìn)行處理,需要的朋友可以參考下
    2023-10-10
  • Java中HashMap和HashTable區(qū)別

    Java中HashMap和HashTable區(qū)別

    HashMap和Hashtable都是Java常見的基于哈希表實現(xiàn)的Map接口的實現(xiàn)類,本文主要介紹了Java中HashMap和HashTable區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Spring Cache擴(kuò)展功能實現(xiàn)過程解析

    Spring Cache擴(kuò)展功能實現(xiàn)過程解析

    這篇文章主要介紹了Spring Cache擴(kuò)展功能實現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java異或技操作給任意的文件加密原理及使用詳解

    Java異或技操作給任意的文件加密原理及使用詳解

    這篇文章主要介紹了Java異或技操作給任意的文件加密原理及使用詳解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • 淺談Java中Collection和Collections的區(qū)別

    淺談Java中Collection和Collections的區(qū)別

    下面小編就為大家?guī)硪黄獪\談Java中Collection和Collections的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • SpringBoot集成RbbitMQ隊列踩坑記錄

    SpringBoot集成RbbitMQ隊列踩坑記錄

    這篇文章主要介紹了SpringBoot集成RbbitMQ隊列踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java 多線程的同步代碼塊詳解

    Java 多線程的同步代碼塊詳解

    這篇文章主要介紹了Java 多線程的同步代碼塊,使用synchronized關(guān)鍵字創(chuàng)建線程同步方法是實現(xiàn)線程同步的關(guān)鍵,需要的朋友可以參考下
    2021-10-10
  • ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解

    ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解

    這篇文章主要介紹了ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解,Rocketmq 消費(fèi)者在高峰期希望手動減少消費(fèi)線程數(shù),通過DefaultMQPushConsumer.updateCorePoolSize方法可以調(diào)用內(nèi)部的setCorePoolSize設(shè)置多線程核心線程數(shù),需要的朋友可以參考下
    2023-10-10
  • idea使用war以及war exploded的區(qū)別說明

    idea使用war以及war exploded的區(qū)別說明

    本文詳細(xì)解析了war與warexploded兩種部署方式的差異及步驟,war方式是先打包成war包,再部署到服務(wù)器上;warexploded方式是直接把文件夾、class文件等移到Tomcat上部署,支持熱部署,開發(fā)時常用,文章分別列出了warexploded模式和war包形式的具體操作步驟
    2024-10-10

最新評論