日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Runnable接口與Thread類的區(qū)別

 燮羽 2010-12-19

什么時候讓線程實現(xiàn)Runnable接口,什么時候讓線程繼承Thread類?

JDK幫助文檔中的原話:Runnable 接口應(yīng)該由那些打算通過某一線程執(zhí)行其實例的類來實現(xiàn)
(不明白是啥意思)
孫鑫老師的原話:當(dāng)不需要改變一個線程中除了run()方法以外的其他方法時,讓線程實現(xiàn)Runnable接口。
(明白是什么意思,但不知道有什么用      汗!!!)

如果讓一個線程實現(xiàn)Runnable接口,那么當(dāng)調(diào)用這個線程的對象開辟多個線程時,可以讓這些線程調(diào)用同一個變量;若這個線程是由繼承Thread類而來,則要通過內(nèi)部類來實現(xiàn)上述功能,利用的就是內(nèi)部類可任意訪問外部變量這一特性。
例子程序:
public class ThreadTest
{
public static void main(String[] args)
{
   MyThread mt=new MyThread();
   new Thread(mt).start();     //通過實現(xiàn)Runnable的類的對象來開辟第一個線程
   new Thread(mt).start();     //通過實現(xiàn)Runnable的類的對象來開辟第二個線程
   new Thread(mt).start();     //通過實現(xiàn)Runnable的類的對象來開辟第三個線程
   //由于這三個線程是通過同一個對象mt開辟的,所以run()里方法訪問的是同一個index
}
}

class MyThread implements Runnable    //實現(xiàn)Runnable接口
{
int index=0;
public void run()
{
   for(;index<=200;)
    System.out.println(Thread.currentThread().getName()+":"+index++);
}
}

------------------------------------------------------------------------------------------------------------------------------------

public class ThreadTest
{
public static void main(String[] args)
{
   MyThread mt=new MyThread();
   mt.getThread().start();       //通過返回內(nèi)部類的對象來開辟第一個線程
   mt.getThread().start();      //通過返回內(nèi)部類的對象來開辟第二個線程
   mt.getThread().start();      //通過返回內(nèi)部類的對象來開辟第三個線程
   //由于這三個線程是通過同一個匿名對象來開辟的,所以run()里方法訪問的是同一個index
}
}

class MyThread
{
int index=0;
private class InnerClass extends Thread    //定義一個內(nèi)部類,繼承Thread
{
   public void run()
   {
    for(;index<=200;)
     System.out.println(getName()+":"+index++);
   }
}
Thread getThread()     //這個函數(shù)的作用是返回InnerClass的一個匿名對象
{
   return new InnerClass();
}
}
//這里有一個問題:如果內(nèi)部類要訪問一個外部變量或方法,那么這個變量或方法必須定義為final,但為什么這里的變量index不用定義為final就可以被內(nèi)部類訪問?
 

Thread和Runnable

1、 認(rèn)識Thread和Runnable

Java中實現(xiàn)多線程有兩種途徑:繼承Thread類或者實現(xiàn)Runnable接口。Runnable是接口,建議用接口的方式生成線程,因為接口可以實現(xiàn)多繼承,況且Runnable只有一個run方法,很適合繼承。在使用Thread的時候只需繼承Thread,并且new一個實例出來,調(diào)用 start()方法即可以啟動一個線程。

Thread Test = new Thread();

Test.start();

在使用Runnable的時候需要先new一個實現(xiàn)Runnable的實例,之后啟動Thread即可。

Test impelements Runnable;

Test t = new Test();

Thread test = new Thread(t);

test.start();

總結(jié):Thread和Runnable是實現(xiàn)java多線程的2種方式,runable是接口,thread是類,建議使用runable實現(xiàn) java多線程,不管如何,最終都需要通過thread.start()來使線程處于可運行狀態(tài)。

2、 認(rèn)識Thread的start和run

1) start:

用start方法來啟動線程,真正實現(xiàn)了多線程運行,這時無需等待run方法體代碼執(zhí)行完畢而直接繼續(xù)執(zhí)行下面的代碼。通過調(diào)用Thread類的 start()方法來啟動一個線程,這時此線程處于就緒(可運行)狀態(tài),并沒有運行,一旦得到cpu時間片,就開始執(zhí)行run()方法,這里方法 run()稱為線程體,它包含了要執(zhí)行的這個線程的內(nèi)容,Run方法運行結(jié)束,此線程隨即終止。

2) run:

run()方法只是類的一個普通方法而已,如果直接調(diào)用Run方法,程序中依然只有主線程這一個線程,其程序執(zhí)行路徑還是只有一條,還是要順序執(zhí)行,還是要等待run方法體執(zhí)行完畢后才可繼續(xù)執(zhí)行下面的代碼,這樣就沒有達(dá)到寫線程的目的。

總結(jié):調(diào)用start方法方可啟動線程,而run方法只是thread的一個普通方法調(diào)用,還是在主線程里執(zhí)行。

3、 線程狀態(tài)說明

線程狀態(tài)從大的方面來說,可歸結(jié)為:初始狀態(tài)、可運行狀態(tài)、不可運行狀態(tài)和消亡狀態(tài),具體可細(xì)分為上圖所示7個狀態(tài),說明如下:

1) 線程的實現(xiàn)有兩種方式,一是繼承Thread類,二是實現(xiàn)Runnable接口,但不管怎樣,當(dāng)我們new了thread實例后,線程就進(jìn)入了初始狀態(tài);

2) 當(dāng)該對象調(diào)用了start()方法,就進(jìn)入可運行狀態(tài);

3) 進(jìn)入可運行狀態(tài)后,當(dāng)該對象被操作系統(tǒng)選中,獲得CPU時間片就會進(jìn)入運行狀態(tài);

4) 進(jìn)入運行狀態(tài)后case就比較多,大致有如下情形:

﹒run()方法或main()方法結(jié)束后,線程就進(jìn)入終止?fàn)顟B(tài);

﹒當(dāng)線程調(diào)用了自身的sleep()方法或其他線程的join()方法,就會進(jìn)入阻塞狀態(tài)(該狀態(tài)既停止當(dāng)前線程,但并不釋放所占有的資源)。當(dāng) sleep()結(jié)束或join()結(jié)束后,該線程進(jìn)入可運行狀態(tài),繼續(xù)等待OS分配時間片;

﹒當(dāng)線程剛進(jìn)入可運行狀態(tài)(注意,還沒運行),發(fā)現(xiàn)將要調(diào)用的資源被鎖牢(synchroniza,lock),將會立即進(jìn)入鎖池狀態(tài),等待獲取鎖標(biāo)記(這時的鎖池里也許已經(jīng)有了其他線程在等待獲取鎖標(biāo)記,這時它們處于隊列狀態(tài),既先到先得),一旦線程獲得鎖標(biāo)記后,就轉(zhuǎn)入可運行狀態(tài),等待OS分配 CPU時間片;

﹒當(dāng)線程調(diào)用wait()方法后會進(jìn)入等待隊列(進(jìn)入這個狀態(tài)會釋放所占有的所有資源,與阻塞狀態(tài)不同),進(jìn)入這個狀態(tài)后,是不能自動喚醒的,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒(由于notify()只是喚醒一個線程,但我們由不能確定具體喚醒的是哪一個線程,也許我們需要喚醒的線程不能夠被喚醒,因此在實際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒后會進(jìn)入鎖池,等待獲取鎖標(biāo)記。

﹒當(dāng)線程調(diào)用stop方法,即可使線程進(jìn)入消亡狀態(tài),但是由于stop方法是不安全的,不鼓勵使用,大家可以通過run方法里的條件變通實現(xiàn)線程的 stop。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多