国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài)

這篇具有很好參考價值的文章主要介紹了Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

前言

一.Java的多線程

1.1多線程的認(rèn)識?

1.2Java多線程的創(chuàng)建方式

1.3Java多線程的生命周期

1.4Java多線程的執(zhí)行機(jī)制

二.創(chuàng)建多線程的四種方式

2.1繼承Thread類

?創(chuàng)建線程?

?Thread的構(gòu)造方法和常見屬性

?2.2.實現(xiàn)Runnable接口

?創(chuàng)建線程

?使用lambda表達(dá)式創(chuàng)建

2.3實現(xiàn)Callable接口創(chuàng)建多線程

?線程的創(chuàng)建

?Callable接口的特點

2.4通過線程池創(chuàng)建多線程

?創(chuàng)建線程


??個人主頁:tq02的博客_CSDN博客-C語言,Java,Java數(shù)據(jù)結(jié)構(gòu)領(lǐng)域博主
?? 本文由 tq02 原創(chuàng),首發(fā)于 CSDN??
???本章講解內(nèi)容:多線程的認(rèn)識、創(chuàng)建方式、及其狀態(tài)

Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài),JavaEE,java,學(xué)習(xí),開發(fā)語言,java-ee

?

??學(xué)習(xí)專欄:??C語言?? ? ? ??JavaSE?? ? ??MySQL基礎(chǔ)??

前言

? ? ? ? 在學(xué)習(xí)多線程之前,我們必須了解什么是線程?作用是什么?而線程的知識又與進(jìn)程有關(guān)系,因此我們需要先了解進(jìn)程再去了解線程,這樣才能更好的學(xué)習(xí)到多線程的知識。本文只是多線程的一部分,多線程涉及的知識點很多很多,鎖啊、線程安全啊、CAS等知識,需要耐心學(xué)習(xí)。

進(jìn)程學(xué)習(xí):http://t.csdn.cn/I4uDU

線程學(xué)習(xí):http://t.csdn.cn/AxYac

一.Java的多線程

1.1多線程的認(rèn)識?

? ? ?多線程,從字面上理解,就是從多個單線程一起執(zhí)行多個任務(wù)。在Java 編程中,已經(jīng)給多線程編程提供了內(nèi)置的支持。多線程是多任務(wù)的一種特別的形式,但多線程使用了更小的cpu資源開銷。 多線程能滿足程序員編寫高效率的程序來達(dá)到充分利用 CPU 的目的。

? ? ? ? 線程本身就是操作系統(tǒng)提供的概念,因此操作系統(tǒng)提供了一些API供程序員使用,而在Java中,也存在一些API供人們使用和編譯。在Java標(biāo)準(zhǔn)庫中Thread類就是用于多線程的創(chuàng)建。

注:創(chuàng)建多線程的方式不僅僅只有Thread類

1.2Java多線程的創(chuàng)建方式

Java語言中,目前可以創(chuàng)建多線程的方式有四種方式:

  1. 繼承Thread類
  2. 實現(xiàn)Runnable接口
  3. 使用lambda表達(dá)式(基于Runnable接口搭配內(nèi)部類的優(yōu)化)
  4. 使用線程池
  5. 使用FutureTask類和Callable接口

以上的1、2、5方法可以搭配匿名內(nèi)部類使用,而目前最為常用的方式有:實現(xiàn)Runnable接口、調(diào)用多線程池。

1.3Java多線程的生命周期

Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài),JavaEE,java,學(xué)習(xí),開發(fā)語言,java-ee

?????????新建狀態(tài)、可執(zhí)行狀態(tài)、執(zhí)行狀態(tài)以及死亡狀態(tài)是每一個線程都會發(fā)生,而阻塞狀態(tài)則是選擇性發(fā)生,當(dāng)需要阻塞時,使用sleep()、join()方法。

1.4Java多線程的執(zhí)行機(jī)制

? ? ? ? 當(dāng)Java程序運行時,先創(chuàng)建出一個進(jìn)程,該進(jìn)程里至少包含一個線程主線程,就是負(fù)責(zé)執(zhí)行main方法的線程。然后在mian()方法里創(chuàng)建出其他線程。我們主要學(xué)習(xí)的就是創(chuàng)建和使用線程。

Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài),JavaEE,java,學(xué)習(xí),開發(fā)語言,java-ee

?注:一般情況下,主線程與子線程相互不影響,即子線程結(jié)束,主線程不一定結(jié)束;主線程結(jié)束,子線程不一定結(jié)束;主線程異常,子線程不一定異常;子線程異常,主線程不一定異常。但當(dāng)設(shè)置守護(hù)線程等特殊操作時,主線程與子線程會發(fā)生相互影響。


?

二.創(chuàng)建多線程的四種方式

2.1繼承Thread類

?創(chuàng)建線程?

? ? ? ? 使用Thread類創(chuàng)建線程有2種方式,最基本的實現(xiàn)多線程方式,就是創(chuàng)建一個類繼承Thread類,然后再實例化該類。可實例化多個線程。

1.繼承Thread類創(chuàng)建一個線程

class MyThread extends Thread {
    @Override
    public void run() {
    System.out.println("這里是線程運行的代碼");
    }
}

public class Text{
     public static void main(String[] args) {
        //創(chuàng)建MyThread實例
      MyThread t1=new MyThread();
       //調(diào)用start方法啟動線程
     t1.start();
    }
}      

注:繼承Thread類需要重寫run()方法,而調(diào)用的是start()方法,而不是run()方法,start()是啟動線程,而run()則是執(zhí)行方法。

2.匿名內(nèi)部類創(chuàng)建 Thread 子類對象

// 使用匿名類創(chuàng)建 Thread 子類對象
Thread t1 = new Thread() {
    @Override
    public void run() {
    System.out.println("使用匿名類創(chuàng)建 Thread 子類對象");
    }
};
    //啟動線程
    t1.start();

:該方法不需要繼承其他類,而是直接實例化Thread類和使用匿名內(nèi)部類。?

?Thread的構(gòu)造方法和常見屬性

Thread構(gòu)造方法:

構(gòu)造方法 解釋
Thread() 創(chuàng)建線程
Thread(Runnable 對象名) 使用Runnable對象創(chuàng)建線程
Thread(String 線程名) 創(chuàng)建線程對象,并命名
Thread(Runnable 對象名,String 線程名) 使用Runnable對象創(chuàng)建線程對象,并命名

常見屬性:

屬性 獲取方法
ID getId()
名稱 getName()
狀態(tài) getState()
優(yōu)先級 getPriority()
是否有后臺線程 isDaemon()
是否存活 isAlive()
是否中斷 isInterrupted()

ID 是線程的唯一標(biāo)識,不同線程不會重復(fù)
名稱是各種調(diào)試工具用到

其中重要的是前臺和后臺線程

  1. 前臺線程,會影響到進(jìn)程結(jié)束,如果前臺進(jìn)程沒有執(zhí)行完畢,進(jìn)程不會結(jié)束
  2. 后臺線程,也稱守護(hù)線程,當(dāng)主線程結(jié)束時,進(jìn)程結(jié)束,后臺線程無論是否還在執(zhí)行也結(jié)束

?Java多線程當(dāng)中默認(rèn)為前臺線程,也可以通過setDaemon方法設(shè)置,false

存活是指線程是否執(zhí)行結(jié)束。中斷是指讓正在執(zhí)行的線程強行結(jié)束。類似循環(huán)的break;


?2.2.實現(xiàn)Runnable接口

?創(chuàng)建線程

????????Runnable接口,將需要執(zhí)行的線程放入其中,再通過Runnable和Thread配合,就可以進(jìn)行線程的實現(xiàn)。而方法有2種。

第一種:創(chuàng)建Thread類實例,調(diào)用構(gòu)造方法時,將Runnable對象傳參

class MyRunnable implements Runnable {
    @Override
    public void run() {
    System.out.println("這里是線程運行的代碼");
    }
}
    
    //創(chuàng)建Thread類實例
Thread t = new Thread(new MyRunnable());
    //調(diào)用start()方法
    t.start();

? ? ? ? 實現(xiàn)一個接口Runnable,然后重寫run方法,再將Runnable實例化出的對象,放入Thread的構(gòu)造函數(shù)Thread(Runnable 對象名),就可以實現(xiàn)線程的執(zhí)行。

第二種:創(chuàng)建Thread類實例,搭配使用匿名內(nèi)部類創(chuàng)建Runnable子類對象

// 使用匿名類創(chuàng)建 Runnable 子類對象
Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("使用匿名類創(chuàng)建 Runnable 子類對象");
    }
});

????????這種方法更為的簡便,直接在匿名內(nèi)部類當(dāng)中重寫run()方法,在run()方法內(nèi)部寫上需要執(zhí)行的操作。

?使用lambda表達(dá)式創(chuàng)建

? ? ? ? lambda表達(dá)式用于匿名內(nèi)部類和接口的情況,而創(chuàng)建Thread類時,搭配匿名內(nèi)部類創(chuàng)建了Runnable子類對象,因此可以使用lambda表達(dá)式的方法簡化操作。

lambda表達(dá)式的學(xué)習(xí):http://t.csdn.cn/VxRLy

代碼示例:

// 使用 lambda 表達(dá)式創(chuàng)建 Runnable 子類對象
Thread t4 = new Thread(() -> {
    System.out.println("使用匿名類創(chuàng)建 Thread 子類對象");
});

如果看不懂lambda表達(dá)式,你就記住這是一種創(chuàng)建線程的方法,不去理解。

注:相比前幾種創(chuàng)建方式,使用lambda表達(dá)式創(chuàng)建更為方便簡單。

2.3實現(xiàn)Callable接口創(chuàng)建多線程

?線程的創(chuàng)建

?Callable 是一個 interface . 使用時需要創(chuàng)建utureTask類的對象,相當(dāng)于把線程封裝了一個 "返回值". 方便程序猿借助多線程的方式計算結(jié)果.該方法是基于jdk5.0之后新增的方法,

方法步驟:

  1. 創(chuàng)建一個實現(xiàn)Callable接口的類。
  2. 在這個實現(xiàn)類中實現(xiàn)Callable接口的call()方法,并創(chuàng)建這個類的對象。? ? ? ?
  3. 將這個Callable接口實現(xiàn)類的對象作為參數(shù)傳遞到FutureTask類的構(gòu)造器中,創(chuàng)建FutureTask類的對象。? ? ? ?
  4. 將這個FutureTask類的對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對象,并調(diào)用這個對象的start()方法。
  5. 在主線程中調(diào)用 futureTask.get() 能夠阻塞等待新線程計算完畢. 并獲取到 FutureTask 中的結(jié)
    果。

代碼示例:

Callable<Integer> callable = new Callable<Integer>() {
        @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 1000; i++) {
        sum += i;
    }
    return sum;
    }
};
    FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread t = new Thread(futureTask);
            t.start();
        int result = futureTask.get();
        System.out.println(result);

?Callable接口的特點

  1. Callable 和 Runnable 相對, 都是描述一個 "任務(wù)". Callable 描述的是帶有返回值的任務(wù),Runnable 描述的是不帶返回值的任務(wù).
  2. Callable 通常需要搭配 FutureTask 來使用. FutureTask 用來保存 Callable 的返回結(jié)果. 因為
  3. Callable 往往是在另一個線程中執(zhí)行的, 啥時候執(zhí)行完并不確定.
  4. FutureTask 就可以負(fù)責(zé)這個等待結(jié)果出來的工作.

2.4通過線程池創(chuàng)建多線程

????????雖然創(chuàng)建銷毀線程比創(chuàng)建銷毀進(jìn)程更輕量, 但是在頻繁創(chuàng)建銷毀線程的時候還是會比較低效.
線程池就是為了解決這個問題. 如果某個線程不再使用了, 并不是真正把線程釋放, 而是放到一個 "池子"中, 下次如果需要用到線程就直接從池子中取, 不必通過系統(tǒng)來創(chuàng)建了.

?創(chuàng)建線程

1、線程池的使用,需要使用以下類:?

  • Executors 是一個工廠類, 能夠創(chuàng)建幾種不同風(fēng)格的線程池.
  • ExecutorService 表示一個線程池實例.
  • ExecutorService 的 submit 方法能夠向線程池中提交若干個任務(wù).

2、Executors 創(chuàng)建的幾種風(fēng)格線程池:

實例化一個線程池格式:ExecutorService pool = Executors.方法();

創(chuàng)建線程池種類 解釋
?Executors.newFixedThreadPool(int? Num threads)? 創(chuàng)建固定線程數(shù)的線程池
?Executors.newSingleThreadExecutor() 創(chuàng)建只包含單個線程的線程池.
?Executors.newCachedThreadPool() 創(chuàng)建線程數(shù)目動態(tài)增長的線程池.
?Executors.newScheduledThreadPool(int corePoolSize)?

設(shè)定延遲時間后執(zhí)行命令,或者定期執(zhí)行命令. 是

進(jìn)階版的 Timer.

注:Executors 本質(zhì)上是 ThreadPoolExecutor 類的封裝

代碼示例:

ExecutorService pool = Executors.newFixedThreadPool(10);
    pool.submit(new Runnable() {
        @Override
    public void run() {
        System.out.println("hello");
    }
});
    //線程池使用結(jié)束之后需要使用shutdown()關(guān)閉
     pool.shutdown();

三.線程的狀態(tài)

????????線程的狀態(tài)是一個枚舉類型 Thread.State,而線程的狀態(tài)一共有6種,6種狀態(tài)定義在Thread類的State枚舉中。

  1. 初始狀態(tài)(NEW):線程對象被創(chuàng)建但尚未調(diào)用start()方法。
  2. 就緒狀態(tài)(RUNNABLE):線程處于可運行線程池中,等待被線程調(diào)度選中獲取CPU的使用權(quán)。就緒狀態(tài)分為兩種情況,一是線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start()方法,此時線程處于某個線程拿到對象鎖、當(dāng)前線程時間片用完調(diào)用yield()方法、鎖池里的線程拿到對象鎖后,這些線程也將進(jìn)入就緒狀態(tài)。
  3. 運行狀態(tài)(RUNNABLE之RUNNING):線程正在被執(zhí)行,具體來說就是線程獲得了CPU的使用權(quán)。
  4. 阻塞狀態(tài)(BLOCKED):線程阻塞于鎖,即線程在等待獲得對象鎖。
  5. 等待狀態(tài)(WAITING):線程需要等待其他線程做出一些特定動作,比如等待其他線程的通知或中斷。
  6. 超時等待狀態(tài)(TIMED_WAITING):與等待狀態(tài)不同的是,超過指定時間后會自動返回。
  7. 終止?fàn)顟B(tài)(TERMINATED):線程的run()方法執(zhí)行完成,或者主線程的main()方法執(zhí)行完成,線程終止。終止?fàn)顟B(tài)的線程不能再被復(fù)生。如果在終止?fàn)顟B(tài)的線程上調(diào)用start()方法,會拋出java.lang.IllegalThreadStateException異常。

注:之前的 isAlive() 方法,可以認(rèn)為是處于不是 NEW 和 TERMINATED 的狀態(tài)都是活著

?

3.1狀態(tài)的抽象說明?

狀態(tài)圖:?

Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài),JavaEE,java,學(xué)習(xí),開發(fā)語言,java-ee??

  1. 初始狀態(tài)(NEW):剛剛拿到銀行卡
  2. 就緒狀態(tài)(RUNNABLE):排隊等待中
  3. 運行狀態(tài)(RUNNABLE之RUNNING):開始與柜臺人員進(jìn)行交流取錢
  4. 阻塞狀態(tài)(BLOCKED):阻塞了,相當(dāng)于有人提前預(yù)約了取錢,你只能等待他結(jié)束
  5. 等待狀態(tài)(WAITING):使用了wait()等待,例如柜臺人員有一點事情,讓你等到他回來
  6. 超時等待狀態(tài)(TIMED_WAITING):使用了sleep(),柜臺人員告訴了你等他多久;使用join()方法,就是你和你朋友同時在取錢,取錢到一半你說先停下來,我朋友那邊取完了你再取。

????????多線程的概念、創(chuàng)建、狀態(tài)的講解本章已經(jīng)結(jié)束了,而后期還有很多線程操作、線程安全、鎖等知識,因此多線程是一個極為復(fù)雜并且重要的知識。文章來源地址http://www.zghlxwxcb.cn/news/detail-625013.html

到了這里,關(guān)于Java多線程(1)---多線程認(rèn)識、四種創(chuàng)建方式以及線程狀態(tài)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包