<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的Java路上那些事兒

    快樂成長(zhǎng)
    posts - 110, comments - 101, trackbacks - 0, articles - 7
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
    在java中可有兩種方式實(shí)現(xiàn)多線程,一種是繼承Thread類,一種是實(shí)現(xiàn)Runnable接口;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í)行,并沒有相互運(yùn)行。在JDK的文檔中可以發(fā)現(xiàn),一旦調(diào)用start()方法,則會(huì)通過 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源程序,通過此代碼找到Thread中的start()方法的定義,可以發(fā)現(xiàn)此方法中使用了 private native void start0();其中native關(guān)鍵字表示可以調(diào)用操作系統(tǒng)的底層函數(shù),那么這樣的技術(shù)成為JNI技術(shù)(java Native Interface)

    Runnable接口
    在實(shí)際開發(fā)中一個(gè)多線程的操作很少使用Thread類,而是通過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定義的子類中沒有start()方法,只有Thread類中才有。此時(shí)觀察Thread類,有一個(gè)構(gòu)造方法:public Thread(Runnable targer)
    此構(gòu)造方法接受Runnable的子類實(shí)例,也就是說可以通過Thread類來啟動(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類有如下好處:
    ->避免點(diǎn)繼承的局限,一個(gè)類可以繼承多個(gè)接口。
    ->適合于資源的共享
    以賣票程序?yàn)槔ㄟ^Thread類完成:
    package org.demo.dff;
    class MyThread extends Thread{
    private int ticket=10;
    public void run(){
    for(int i=0;i<20;i++){
    if(this.ticket>0){
    System.out.println("賣票:ticket"+this.ticket--);
    }
    }
    }
    };
    下面通過三個(gè)線程對(duì)象,同時(shí)賣票:
    package org.demo.dff;
    public class ThreadTicket {
    public static void main(String[] args) {
    MyThread mt1=new MyThread();
    MyThread mt2=new MyThread();
    MyThread mt3=new MyThread();
    mt1.start();//每個(gè)線程都各賣了10張,共賣了30張票
    mt2.start();//但實(shí)際只有10張票,每個(gè)線程都賣自己的票
    mt3.start();//沒有達(dá)到資源共享
    }
    }
    如果用Runnable就可以實(shí)現(xiàn)資源共享,下面看例子:
    package org.demo.runnable;
    class MyThread implements Runnable{
    private int ticket=10;
    public void run(){
    for(int i=0;i<20;i++){
    if(this.ticket>0){
    System.out.println("賣票:ticket"+this.ticket--);
    }
    }
    }
    }
    package org.demo.runnable;
    public class RunnableTicket {
    public static void main(String[] args) {
    MyThread mt=new MyThread();
    new Thread(mt).start();//同一個(gè)mt,但是在Thread中就不可以,如果用同一
    new Thread(mt).start();//個(gè)實(shí)例化對(duì)象mt,就會(huì)出現(xiàn)異常
    new Thread(mt).start();
    }
    };
    雖然現(xiàn)在程序中有三個(gè)線程,但是一共賣了10張票,也就是說使用Runnable實(shí)現(xiàn)多線程可以達(dá)到資源共享目的。

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

    因?yàn)橐粋€(gè)線程只能啟動(dòng)一次,通過Thread實(shí)現(xiàn)線程時(shí),線程和線程所要執(zhí)行的任務(wù)是捆綁在一起的。也就使得一個(gè)任務(wù)只能啟動(dòng)一個(gè)線程,不同的線程執(zhí)行的任務(wù)是不相同的,所以沒有必要,也不能讓兩個(gè)線程共享彼此任務(wù)中的資源。

    一個(gè)任務(wù)可以啟動(dòng)多個(gè)線程,通過Runnable方式實(shí)現(xiàn)的線程,實(shí)際是開辟一個(gè)線程,將任務(wù)傳遞進(jìn)去,由此線程執(zhí)行。可以實(shí)例化多個(gè) Thread對(duì)象,將同一任務(wù)傳遞進(jìn)去,也就是一個(gè)任務(wù)可以啟動(dòng)多個(gè)線程來執(zhí)行它。這些線程執(zhí)行的是同一個(gè)任務(wù),所以他們的資源是共享。

    兩種不同的線程實(shí)現(xiàn)方式本身就決定了其是否能進(jìn)行資源共享。



    評(píng)論

    # re: java 多線程 Thread與Runnable的區(qū)別  回復(fù)  更多評(píng)論   

    2012-02-17 11:19 by 初入江湖
    寫的不錯(cuò)

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 乱淫片免费影院观看| 亚洲乱码一二三四区国产| 久久精品国产亚洲精品| 男人的天堂亚洲一区二区三区 | 特级aa**毛片免费观看| 亚洲sm另类一区二区三区| 亚洲精品美女久久7777777| 亚洲国产综合AV在线观看| 国产午夜亚洲精品不卡电影| 亚洲风情亚Aⅴ在线发布| 国产成人亚洲综合无| 手机永久免费的AV在线电影网| 一级毛片在播放免费| 精品国产污污免费网站入口在线| 中文字幕成人免费高清在线| 国产免费一区二区三区不卡| 日韩插啊免费视频在线观看| 免费A级毛片无码A∨免费| 三年片在线观看免费大全| 天天摸天天操免费播放小视频| 日韩a在线观看免费观看| 成人亚洲网站www在线观看| 亚洲综合网站色欲色欲| 亚洲三级电影网站| 亚洲免费视频网址| 国产AV无码专区亚洲AV麻豆丫 | 亚洲视频免费在线看| 丁香婷婷亚洲六月综合色| 色偷偷亚洲男人天堂| 中文字幕在线免费观看视频| 99在线视频免费| 免费爱爱的视频太爽了| 亚洲午夜日韩高清一区| 亚洲色欲色欲综合网站| 亚洲色大成网站www永久网站| 男人j进女人p免费视频| 精品一区二区三区免费毛片爱 | 亚洲高清视频免费| 日本媚薬痉挛在线观看免费| 国产成人精品曰本亚洲79ren| 亚洲综合在线观看视频|