成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

線程Thread類的start()方法和run()方法

Rocko / 3408人閱讀

摘要:一初識(shí)的線程是通過類來實(shí)現(xiàn)的。在生成線程對(duì)象,并沒有調(diào)用該對(duì)象的方法,這是線程處于創(chuàng)建狀態(tài)。如果一個(gè)線程的方法執(zhí)行結(jié)束或者調(diào)用方法后,該線程就會(huì)死亡。對(duì)于已經(jīng)死亡的線程,無法再使用方法令其進(jìn)入就緒。

一、初識(shí)

java的線程是通過java.lang.Thread類來實(shí)現(xiàn)的。VM啟動(dòng)時(shí)會(huì)有一個(gè)由主方法所定義的線程??梢酝ㄟ^創(chuàng)建Thread的實(shí)例來創(chuàng)建新的線程。每個(gè)線程都是通過某個(gè)特定Thread對(duì)象所對(duì)應(yīng)的方法run()來完成其操作的,方法run()稱為線程體。通過調(diào)用Thread類的start()方法來啟動(dòng)一個(gè)線程。

在Java當(dāng)中,線程通常都有五種狀態(tài),創(chuàng)建、就緒、運(yùn)行、阻塞和死亡。

  第一是創(chuàng)建狀態(tài)。在生成線程對(duì)象,并沒有調(diào)用該對(duì)象的start方法,這是線程處于創(chuàng)建狀態(tài)。

  第二是就緒狀態(tài)。當(dāng)調(diào)用了線程對(duì)象的start方法之后,該線程就進(jìn)入了就緒狀態(tài),但是此時(shí)線程調(diào)度程序還沒有把該線程設(shè)置為當(dāng)前線程,此時(shí)處于就緒狀態(tài)。在線程運(yùn)行之后,從等待或者睡眠中回來之后,也會(huì)處于就緒狀態(tài)。

  第三是運(yùn)行狀態(tài)。線程調(diào)度程序?qū)⑻幱诰途w狀態(tài)的線程設(shè)置為當(dāng)前線程,此時(shí)線程就進(jìn)入了運(yùn)行狀態(tài),開始運(yùn)行run函數(shù)當(dāng)中的代碼。

  第四是阻塞狀態(tài)。線程正在運(yùn)行的時(shí)候,被暫停,通常是為了等待某個(gè)時(shí)間的發(fā)生(比如說某項(xiàng)資源就緒)之后再繼續(xù)運(yùn)行。sleep,suspend,wait等方法都可以導(dǎo)致線程阻塞。

  第五是死亡狀態(tài)。如果一個(gè)線程的run方法執(zhí)行結(jié)束或者調(diào)用stop方法后,該線程就會(huì)死亡。對(duì)于已經(jīng)死亡的線程,無法再使用start方法令其進(jìn)入就緒。

二、start()方法
1、為什么需要start方法;它的作用是什么?

start()方法來啟動(dòng)線程,真正實(shí)現(xiàn)了多線程運(yùn)行。
start方法的作用就是將線程由NEW狀態(tài),變?yōu)镽UNABLE狀態(tài)。當(dāng)線程創(chuàng)建成功時(shí),線程處于NEW(新建)狀態(tài),如果你不調(diào)用start( )方法,那么線程永遠(yuǎn)處于NEW狀態(tài)。調(diào)用start( )后,才會(huì)變?yōu)镽UNABLE狀態(tài),線程才可以運(yùn)行。

2、調(diào)用start()方法后,線程是不是馬上執(zhí)行?

線程不是馬上執(zhí)行的;準(zhǔn)確來說,調(diào)用start( )方法后,線程的狀態(tài)是“READY(就緒)”狀態(tài),而不是“RUNNING(運(yùn)行中)”狀態(tài)(關(guān)于線程的狀態(tài)詳細(xì)。線程要等待CPU調(diào)度,不同的JVM有不同的調(diào)度算法,線程何時(shí)被調(diào)度是未知的。因此,start()方法的被調(diào)用順序不能決定線程的執(zhí)行順序

注意:
由于在線程的生命周期中,線程的狀態(tài)由NEW ----> RUNABLE只會(huì)發(fā)生一次,因此,一個(gè)線程只能調(diào)用start()方法一次,多次啟動(dòng)一個(gè)線程是非法的。特別是當(dāng)線程已經(jīng)結(jié)束執(zhí)行后,不能再重新啟動(dòng)。

三、run( )方法
1、run方法又是一個(gè)什么樣的方法?run方法與start方法有什么關(guān)聯(lián)?

run()方法當(dāng)作普通方法的方式調(diào)用
run( )其實(shí)是一個(gè)普通方法,只不過當(dāng)線程調(diào)用了start( )方法后,一旦線程被CPU調(diào)度,處于運(yùn)行狀態(tài),那么線程才會(huì)去調(diào)用這個(gè)run()方法;

2、run()方法的執(zhí)行是不是需要線程調(diào)用start()方法

上面說了,run()方法是一個(gè)普通的對(duì)象方法,因此,不需要線程調(diào)用start()后才可以調(diào)用的。可以線程對(duì)象可以隨時(shí)隨地調(diào)用run方法。

Example1:
  Thread t1 = new Thread(new MyTask(1));
  Thread t2 = new Thread(new MyTask(2));
     t1.run();
     t2.run();

上面的輸出結(jié)果是固定的:

count的值:1
count的值:2

再看另一個(gè)實(shí)例:

 Thread t1 = new Thread(new MyTask());
 Thread t2 = new Thread(new MyTask());
     t1.start();
     t2.start();

這個(gè)輸出結(jié)果不是固定的,因?yàn)榫€程的運(yùn)行沒法預(yù)測(cè)。運(yùn)行結(jié)果可能不一樣。

MyTask 類:

//實(shí)現(xiàn)Runnable接口
class MyTask implements Runnable{

    int count;
    public MyTask(int count) {
        this.count=count;
    }
    @Override
    public void run() {
        System.out.println("count的值:"+count);
    }
}
Example2:

1、用start方法啟動(dòng)線程

    public class Main {  
      
        public static void main(String[] args) {  
            Thread t1 = new Thread(new T1());  
            Thread t2 = new Thread(new T2());  
            t1.start();  
            t2.start();  
        }  
      
    }  
      
    class T1 implements Runnable {  
        public void run() {  
            try {  
                for(int i=0;i<10;i++){  
                    System.out.println(i);  
                    Thread.sleep(100);  //模擬耗時(shí)任務(wù)  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
      
    class T2 implements Runnable {  
        public void run() {  
            try {  
                for(int i=0;i>-10;i--){  
                    System.out.println(i);  
                    Thread.sleep(100);  //模擬耗時(shí)任務(wù)  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  

結(jié)果:

說明兩線程是并發(fā)執(zhí)行的。

2、先用run方法啟動(dòng)線程
將上面的start()改為run()

    public class Main {  
      
        public static void main(String[] args) {  
            Thread t1 = new Thread(new T1());  
            Thread t2 = new Thread(new T2());  
            t1.run();  
            t2.run();  
        }  
      
    }  


說明兩線程實(shí)際是順序執(zhí)行的。

總結(jié):

通過實(shí)例1和實(shí)例和我們可以知道start方法是用于啟動(dòng)線程的,可以實(shí)現(xiàn)并發(fā),而run方法只是一個(gè)普通方法,是不能實(shí)現(xiàn)并發(fā)的,只是在并發(fā)執(zhí)行的時(shí)候會(huì)調(diào)用。

說到這,不知道小伙伴們有沒有明白這兩個(gè)方法的區(qū)別,如果還有疑問,可以留言交流。

四、start()方法和run()方法源碼解析(基于JDK1.7.0_40)
    public synchronized void start() {  
        // 如果線程不是"就緒狀態(tài)",則拋出異常!  
        if (threadStatus != 0)  
            throw new IllegalThreadStateException();  
        // 將線程添加到ThreadGroup中  
        group.add(this);  
        boolean started = false;  
        try {  
            // 通過start0()啟動(dòng)線程,新線程會(huì)調(diào)用run()方法  
            start0();  
            // 設(shè)置started標(biāo)記=true  
            started = true;  
        } finally {  
            try {  
                if (!started) {  
                    group.threadStartFailed(this);  
                }  
            } catch (Throwable ignore) {  
            }  
        }  
    }  
public void run() {  
    if (target != null) {  
        target.run();  
    }  
} 
五、真正理解Thread類

Thread類的對(duì)象其實(shí)也是一個(gè)java對(duì)象,只不過每一個(gè)Thread類的對(duì)象對(duì)應(yīng)著一個(gè)線程。Thread類的對(duì)象就是提供給用戶用于操作線程、獲取線程的信息。真正的底層線程用戶是看不到的了。
因此,當(dāng)一個(gè)線程結(jié)束了,死掉了,對(duì)應(yīng)的Thread的對(duì)象仍能調(diào)用,除了start( )方法外的所有方法(死亡的線程不能再次啟動(dòng)),如run( )、getName( )、getPriority()等等

//簡單起見,使用匿名內(nèi)部類的方法來創(chuàng)建線程
    Thread thread = new Thread(){
        @Override
        public void run() {
            System.out.println("Thread對(duì)象的run方法被執(zhí)行了");
        }
    };
    //線程啟動(dòng)
    thread.start();
    
    //用循環(huán)去監(jiān)聽線程thread是否還活著,只有當(dāng)線程thread已經(jīng)結(jié)束了,才跳出循環(huán)
    while(thread.isAlive()){}
    //線程thread結(jié)束了,但仍能調(diào)用thread對(duì)象的大部分方法
    System.out.println("線程"+thread.getName()+"的狀態(tài):"+thread.getState()+"---優(yōu)先級(jí):"+thread.getPriority());
    //調(diào)用run方法
    thread.run();
    //當(dāng)線程結(jié)束時(shí),start方法不能調(diào)用,下面的方法將會(huì)拋出異常
    thread.start();
參考資料

http://www.cnblogs.com/jinggo...

https://blog.csdn.net/u010568...

https://blog.csdn.net/xuxurui...

文章有不當(dāng)之處,歡迎指正,你也可以關(guān)注我的微信公眾號(hào):好好學(xué)java,獲取優(yōu)質(zhì)學(xué)習(xí)資源。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69525.html

相關(guān)文章

  • Thread類源碼解讀(1)——如何創(chuàng)建啟動(dòng)線程

    摘要:無論它由子類覆寫提供還是由對(duì)象提供,方法最終都會(huì)新建一個(gè)線程來執(zhí)行這個(gè)方法。這種方法看上去好像復(fù)雜了好多,但其實(shí)就是通過新建類的對(duì)象來創(chuàng)建線程??偨Y(jié)在中,創(chuàng)建一個(gè)線程,有且僅有一種方式創(chuàng)建一個(gè)類實(shí)例,并調(diào)用它的方法。 前言 系列文章目錄 談到線程同步與通信,線程本身的概念是繞不開的,而進(jìn)程和線程的概念已經(jīng)是老生常談的話題了,一些基本的概念本文就不再討論了,本篇僅僅致力于通過源碼,了解...

    stefanieliang 評(píng)論0 收藏0
  • Java 多線程

    摘要:當(dāng)一個(gè)程序運(yùn)行時(shí),內(nèi)部可能包含了多個(gè)順序執(zhí)行流,每個(gè)順序執(zhí)行流就是一個(gè)線程所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程。線程也被稱作輕量級(jí)進(jìn)程,線程是進(jìn)程的執(zhí)行單元。在線程的生命周期中,它要經(jīng)過新 線程概述 線程和進(jìn)程 幾乎所有的操作系統(tǒng)都支持同時(shí)運(yùn)行多個(gè)任務(wù),一個(gè)任務(wù)通常就是一個(gè)程序,每個(gè)運(yùn)行中的程序就是一個(gè)進(jìn)程。當(dāng)一個(gè)程序運(yùn)行時(shí),內(nèi)部可能包含了多個(gè)順序執(zhí)行流,每個(gè)順序執(zhí)行流就是一個(gè)線程 所有運(yùn)...

    zorro 評(píng)論0 收藏0
  • Java多線程:Java多線程基礎(chǔ)

    摘要:另外一種方法是,將這個(gè)線程加入一個(gè)線程組,在線程組里重寫方法來處理拋出的異常,這時(shí)線程組的作用相當(dāng)于實(shí)現(xiàn)了的類。使用對(duì)象處理異常格式錯(cuò)誤使用線程組處理異常測(cè)試異常 感性地理解一下什么是線程? 線程這個(gè)概念其實(shí)是比較抽象的,雖然依照教科書上的說法: 進(jìn)程是從系統(tǒng)獲取資源的最小單位,線程是程序執(zhí)行的最小單位。程序是靜態(tài)存在于磁盤上的一段文本,進(jìn)程運(yùn)行這段文本記錄的命令。 也就是說,進(jìn)程從系...

    CHENGKANG 評(píng)論0 收藏0
  • 如何創(chuàng)建并運(yùn)行java線程

    摘要:例子如下可以用如下方式創(chuàng)建并運(yùn)行上述子類一旦線程啟動(dòng)后方法就會(huì)立即返回,而不會(huì)等待到方法執(zhí)行完畢才返回。但是,事實(shí)上方法并非是由剛創(chuàng)建的新線程所執(zhí)行的,而是被創(chuàng)建新線程的當(dāng)前線程所執(zhí)行了。這是因?yàn)榫€程是并行執(zhí)行而非順序的。 showImg(http://segmentfault.com/img/bVbN5u); Java線程類也是一個(gè)object類,它的實(shí)例都繼承自java.lang...

    宋華 評(píng)論0 收藏0
  • 什么是Java多線程?

    摘要:是不能直接調(diào)用系統(tǒng)功能的,所以,我們沒有辦法直接實(shí)現(xiàn)多線程程序。通過查看,我們知道了有種方式實(shí)現(xiàn)多線程程序。使用的是搶占式調(diào)度模型演示如何設(shè)置和獲取線程優(yōu)先級(jí)返回線程對(duì)象的優(yōu)先級(jí)更改線程的優(yōu)先級(jí)線程默認(rèn)優(yōu)先級(jí)是。線程優(yōu)先級(jí)的范圍是。 第五階段 多線程 前言: 一個(gè)場景:周末,帶著并不存在的女票去看電影,無論是現(xiàn)場買票也好,又或是手機(jī)買票也好,上一秒還有位置,遲鈍了一下以后,就顯示該座位...

    高璐 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<