Java中Runnable和Thread以及Callable的區(qū)別

在java中朵你,其實(shí)java中實(shí)現(xiàn) 多線程有三種方法,一種是繼承Thread類揣非;第二種是實(shí)現(xiàn)Runnable接口抡医;第三種是實(shí)現(xiàn)Callable接口。

1早敬,繼承Thread
Thread類是在java.lang包中定義的忌傻。一個(gè)類只要繼承了Thread類同時(shí)覆寫了本類中的run()方法就可以實(shí)現(xiàn)多線程操作了,但是一個(gè)類只能繼承一個(gè)父類搞监,這是此方法的局限水孩。

下面看例子:

package org.thread.demo;
  class MyThread extends Thread{
  private String name;
  public MyThread(String name) {
  super();
  this.name = name;
  }
  public void run(){
  for(int i=0;i<10;i++){
  System.out.println("線程開始:"+this.name+",i="+i);
  }
  }
  }
  package org.thread.demo;
  public class ThreadDemo01 {
  public static void main(String[] args) {
  MyThread mt1=new MyThread("線程a");
  MyThread mt2=new MyThread("線程b");
  mt1.run();
  mt2.run();
  }
  }

但是,此時(shí)結(jié)果很有規(guī)律琐驴,先第一個(gè)對(duì)象執(zhí)行俘种,然后第二個(gè)對(duì)象執(zhí)行,并沒(méi)有相互運(yùn)行绝淡。在JDK的文檔中可以發(fā)現(xiàn)宙刘,一旦調(diào)用start()方法,則會(huì)通過(guò)JVM找到run()方法牢酵。下面啟動(dòng)start()方法啟動(dòng)線程:

package org.thread.demo;  
public class ThreadDemo01 {  
public static void main(String[] args) {  
MyThread mt1=new MyThread("線程a");  
MyThread mt2=new MyThread("線程b");  
mt1.start();  
mt2.start();  
}  
}; 

這樣程序可以正常完成交互式運(yùn)行悬包。那么為啥非要使用start();方法啟動(dòng)多線程呢?

在JDK的安裝路徑下馍乙,src.zip是全部的java源程序布近,通過(guò)此代碼找到Thread中的start()方法的定義,可以發(fā)現(xiàn)此方法中使用了private native void start0();其中native關(guān)鍵字表示可以調(diào)用操作系統(tǒng)的底層函數(shù)潘拨,那么這樣的技術(shù)成為JNI技術(shù)(java Native Interface)

2,Runnable接口
在實(shí)際開發(fā)中一個(gè)多線程的操作很少使用Thread類饶号,而是通過(guò)Runnable接口

public interface Runnable{  
public void run();  
} 
例子:
package org.runnable.demo;  
class MyThread implements Runnable{  
private String name;  
public MyThread(String name) {  
this.name = name;  
}
public void run(){  
for(int i=0;i<100;i++){  
System.out.println("線程開始:"+this.name+",i="+i);  
}  
}  
}; 

使用Runnable定義的子類中沒(méi)有start()方法铁追,只有Thread類中才有。此時(shí)觀察Thread類茫船,有一個(gè)構(gòu)造方法:public Thread(Runnable targer)此構(gòu)造方法接受Runnable的子類實(shí)例琅束,也就是說(shuō)可以通過(guò)Thread類來(lái)啟動(dòng)Runnable實(shí)現(xiàn)的多線程扭屁。(start()可以協(xié)調(diào)系統(tǒng)的資源):

package org.runnable.demo;  
import org.runnable.demo.MyThread;  
public class ThreadDemo01 {  
public static void main(String[] args) {  
MyThread mt1=new MyThread("線程a");  
MyThread mt2=new MyThread("線程b");  
new Thread(mt1).start();  
new Thread(mt2).start();  
}  
} 

兩種實(shí)現(xiàn)方式的區(qū)別和聯(lián)系:

在程序開發(fā)中只要是多線程肯定永遠(yuǎn)以實(shí)現(xiàn)Runnable接口為主,因?yàn)閷?shí)現(xiàn)Runnable接口相比繼承Thread類有如下好處:

1,避免點(diǎn)繼承的局限涩禀,一個(gè)類可以繼承多個(gè)接口料滥。
2,適合于資源的共享

Runnable接口和Thread之間的聯(lián)系:
public class Thread extends Object implements Runnable
發(fā)現(xiàn)Thread類也是Runnable接口的子類。

3艾船,Callable接口
Callable 和 Runnable 的使用方法大同小異葵腹, 區(qū)別在于:
1.Callable 使用 call() 方法, Runnable 使用 run() 方法
2.call() 可以返回值屿岂, 而 run()方法不能返回践宴。
3.call() 可以拋出受檢查的異常,比如ClassNotFoundException爷怀, 而run()不能拋出受檢查的異常阻肩。

Callable示例如下:

Java代碼

class TaskWithResult implements Callable<String> {  
    private int id;  

    public TaskWithResult(int id) {  
        this.id = id;  
    }  

    @Override  
    public String call() throws Exception {  
        return "result of TaskWithResult " + id;  
    }  
}  

public class CallableTest {  
    public static void main(String[] args) throws InterruptedException,  
            ExecutionException {  
        ExecutorService exec = Executors.newCachedThreadPool();  
       //Future 相當(dāng)于是用來(lái)存放Executor執(zhí)行的結(jié)果的一種容器  
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();    
        for (int i = 0; i < 10; i++) {  
            results.add(exec.submit(new TaskWithResult(i)));  
        }  
        for (Future<String> fs : results) {  
            if (fs.isDone()) {  
                System.out.println(fs.get());  
            } else {  
                System.out.println("Future result is not yet complete");  
            }  
        }  
        exec.shutdown();  
    }  
} 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市运授,隨后出現(xiàn)的幾起案子烤惊,更是在濱河造成了極大的恐慌,老刑警劉巖吁朦,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柒室,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡喇完,警方通過(guò)查閱死者的電腦和手機(jī)伦泥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锦溪,“玉大人不脯,你說(shuō)我怎么就攤上這事】陶铮” “怎么了防楷?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)则涯。 經(jīng)常有香客問(wèn)我复局,道長(zhǎng),這世上最難降的妖魔是什么粟判? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任亿昏,我火速辦了婚禮,結(jié)果婚禮上档礁,老公的妹妹穿的比我還像新娘角钩。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布递礼。 她就那樣靜靜地躺著惨险,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脊髓。 梳的紋絲不亂的頭發(fā)上辫愉,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音将硝,去河邊找鬼恭朗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛袋哼,可吹牛的內(nèi)容都是我干的冀墨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼涛贯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼诽嘉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起弟翘,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤虫腋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后稀余,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悦冀,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年睛琳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盒蟆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡师骗,死狀恐怖历等,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辟癌,我是刑警寧澤寒屯,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站黍少,受9級(jí)特大地震影響寡夹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厂置,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一菩掏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧昵济,春花似錦智绸、人聲如沸或颊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至醉顽,卻和暖如春沼溜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背游添。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工系草, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唆涝。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓找都,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親廊酣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子能耻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353