日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程的实现方式-Thread 类,Runnable 接口

發布時間:2025/3/20 java 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程的实现方式-Thread 类,Runnable 接口 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 Java 的 JDK 開發包中,已經自帶了對多線程技術的支持,可以方便地進行多線程編程。實現多線程編程的方式主要有兩種:一種是繼承 Thread 類,另一種是實現 Runnable 接口。下面詳細介紹這兩種具體實現方式。

繼承 Thread 類

在學習如何實現多線程前,先來看看 Thread 類的結構,如下:

public class Thread implements Runnable

從上面的源代碼可以發現,Thread 類實現了 Runnable 接口,它們之間具有多態關系。

其實,使用繼承 Thread 類的方式實現多線程,最大的局限就是不支持多繼承,因為 Java 語言的特點就是單根繼承,所以為了支持多繼承,完全可以實現 Runnable 接口的方式,一邊實現一邊繼承。但用這兩種方式創建的線程在工作時的性質是一樣的,沒有本質的區別。

Thread 類有如下兩個常用構造方法:

public Thread(String threadName) public Thread()

繼承 Thread 類實現線程的語法格式如下:

public class NewThreadName extends Thread { //NewThreadName 類繼承自 Thread 類public void run(){//線程的執行代碼在這里} }

線程實現的業務代碼需要放到 run() 方法中。當一個類繼承 Thread 類后,就可以在該類中覆蓋 run() 方法,將實現線程功能的代碼寫入 run() 方法中,然后同時調用 Thread 類的 start() 方法執行線程,也就是調用 run() 方法。

Thread 對象需要一個任務來執行,任務是指線程在啟動時執行的工作,該工作的功能代碼被寫在 run() 方法中。當執行一個線程程序時,就會自動產生一個線程,主方法正是在這個線程上運行的。當不再啟動其他線程時,該程序就為單線程程序。主方法線程啟動由 Java 虛擬機負責,開發人員負責啟動自己的線程。

如下代碼演示了如何啟動一個線程:

new NewThreadName().start(); //NewThreadName 為繼承自 Thread 的子類

注意:如果 start() 方法調用一個已經啟動的線程,系統將會拋出 IllegalThreadStateException 異常。

例 1
編寫一個 Java 程序演示線程的基本使用方法。這里創建的自定義線程類為 MyThread,此類繼承自 Thread,并在重寫的 run() 中輸出一行字符串。

MyThread 類代碼如下:

public class MyThread extends Thread {@Overridepublic void run(){super.run();System.out.println("這是線程類 MyThread");} }

接下來編寫啟動 MyThread 線程的主方法,代碼如下:

public static void main(String[] args) {MyThread mythread=new MyThread(); //創建一個線程類mythread.start(); //開啟線程System.out.println("運行結束!"); //在主線程中輸出一個字符串 }

運行上面的程序將看到如下所示的運行效果。

運行結束!
這是線程類 MyThread

從上面的運行結果來看,MyThread 類中 run() 方法執行的時間要比主線程晚。這也說明在使用多線程技術時,代碼的運行結果與代碼執行順序或調用順序是無關的。同時也驗證了線程是一個子任務,CPU 以不確定的方式,或者說以隨機的時間來調用線程中的 run() 方法,所以就會出現先打印“運行結束!”,后輸出“這是線程類MyThread”這樣的結果了。

例 2

上面介紹了線程的調用具有隨機性,為了更好地理解這種隨機性這里編寫了一個案例進行演示。

(1) 首先創建自定義的線程類 MyThread01,代碼如下:

public class MyThread extends Thread {public void run(){try {for(int i=0;i<10;i++){int time=(int) (Math.random()*1000);Thread.sleep(time);System.out.println("當前線程名稱:"+Thread.currentThread().getName());}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }

(2) 接下來編寫主線程代碼,在這里除了啟動上面的 MyThread01 線程外,還實現了 MyThread01 線程相同的功能。主線程的代碼如下:

public class Test {public static void main(String[] args){ try{ MyThread thread=new MyThread(); thread.setName("myThread"); thread.start(); for (int i=0;i<10;i++){ int time=(int)(Math.random()*1000); Thread.sleep(time); System.out.println("主線程名稱="+Thread.currentThread().getName()); } }catch(InterruptedException e){ e.printStackTrace(); }}}

在上述代碼中,為了展現出線程具有隨機特性,所以使用隨機數的形式來使線程得到掛起的效果,從而表現出 CPU 執行哪個線程具有不確定性。

MyThread類中的 start() 方法通知“線程規劃器”此線程已經準備就緒,等待調用線程對象的 run() 方法。這個過程其實就是讓系統安排一個時間來調用 Thread 中的 run() 方法,也就是使線程得到運行,啟動線程,具有異步執行的效果。

如果調用代碼 thread.run() 就不是異步執行了,而是同步,那么此線程對象并不交給“線程規劃器”來進行處理,而是由 main 主線程來調用 run() 方法,也就是必須等 run() 方法中的代碼執行完后才可以執行后面的代碼。

這種采用隨機數延時調用線程的方法又稱為異步調用,程序運行的效果如下所示。

當前線程名稱:myThread 主線程名稱=main 主線程名稱=main 主線程名稱=main 當前線程名稱:myThread 主線程名稱=main 主線程名稱=main 當前線程名稱:myThread 當前線程名稱:myThread 主線程名稱=main 當前線程名稱:myThread 主線程名稱=main 當前線程名稱:myThread 主線程名稱=main 當前線程名稱:myThread 主線程名稱=main 當前線程名稱:myThread 主線程名稱=main 當前線程名稱:myThread 當前線程名稱:myThread

例 3
除了異步調用之外,同步執行線程 start() 方法的順序不代表線程啟動的順序。下面創建一個案例演示同步線程的調用。

(1) 首先創建自定義的線程類 MyThread,代碼如下:

public class MyThread extends Thread {private int i;public MyThread(int i){super();this.i=i;}public void run(){System.out.println("當前數字:"+i);} }

(2) 接下來編寫主線程代碼,在這里創建 10 個線程類 MyThread,并按順序依次調用它們的 start() 方法。主線程的代碼如下:

public class Test {public static void main(String[] args){ MyThread t11=new MyThread(1); MyThread t12=new MyThread(2); MyThread t13=new MyThread(3); MyThread t14=new MyThread(4); MyThread t15=new MyThread(5); MyThread t16=new MyThread(6); MyThread t17=new MyThread(7); MyThread t18=new MyThread(8); MyThread t19=new MyThread(9); MyThread t110=new MyThread(10); t11.start(); t12.start(); t13.start(); t14.start(); t15.start(); t16.start(); t17.start(); t18.start(); t19.start(); t110.start(); }}

程序運行后的結果如下所示,從運行結果中可以看到,雖然調用時數字是有序的,但是由于線程執行的隨機性,導致輸出的數字是無序的,而且每次順序都不一樣。

當前數字:1 當前數字:5 當前數字:4 當前數字:2 當前數字:3 當前數字:7 當前數字:6 當前數字:8 當前數字:9 當前數字:10

實現 Runnable 接口

如果要創建的線程類已經有一個父類,這時就不能再繼承 Thread 類,因為 Java 不支持多繼承,所以需要實現 Runnable 接口來應對這樣的情況。

實現 Runnable 接口的語法格式如下:

public class thread extends Object implements Runnable

提示:從 JDK 的 API 中可以發現,實質上 Thread 類實現了 Runnable 接口,其中的 run() 方法正是對 Runnable 接口中 run() 方法的具體實現。

實現 Runnable 接口的程序會創建一個 Thread 對象,并將 Runnable 對象與 Thread 對象相關聯。Thread 類有如下兩個與 Runnable 有關的構造方法:

public Thread(Runnable r); public Thread(Runnable r,String name);

使用上述兩種構造方法之一均可以將 Runnable 對象與 Thread 實例相關聯。使用 Runnable 接口啟動線程的基本步驟如下。

  • 創建一個 Runnable 對象。
  • 使用參數帶 Runnable 對象的構造方法創建 Thread 實例。
  • 調用 start() 方法啟動線程。
  • 通過實現 Runnable 接口創建線程時開發人員首先需要編寫一個實現 Runnable 接口的類,然后實例化該類的對象,這樣就創建了 Runnable 對象。接下來使用相應的構造方法創建 Thread 實例。最后使用該實例調用 Thread 類的 start() 方法啟動線程,如圖 1 所示。


    例 1
    編寫一個簡單的案例演示如何實現 Runnable 接口,以及如何啟動線程。

    (1) 首先創建一個自定義的 MyRmmable 類,讓該類實現 Runnable 接口,并在 run() 方法中輸出一個字符串。代碼如下:

    public class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("MyRunnable運行中!");}}

    (2) 接下來在主線程中編寫代碼,創建一個 MyRunnable 類實例,并將該實例作為參數傳遞給 Thread 類的構造方法,最后調用 Thread 類的 start() 方法啟動線程。具體實現代碼如下:

    public class Test {public static void main(String[] args){ Runnable runnable=new MyRunnable();Thread thread=new Thread(runnable);thread.start();System.out.println("主線程運行結束");}}

    如上述代碼所示,啟動線程的方法非常簡單。運行結果如下所示,同樣驗證了線程執行的隨機性。

    主線程運行結束! MyRunnable運行中!

    注意:要啟動一個新的線程,不是直接調用 Thread 子類對象的 run() 方法,而是調用 Thread 子類的 start() 方法。Thread 類的 start() 方法會產生一個新的線程,該線程用于執行 Thread 子類的 run() 方法。

    兩種方法的比較

    雖然 Thread 類和 Runnable 接口都可以創建線程,但是它們也都有各自的優缺點。

  • 繼承 Thread 類的優缺點
  • 當一個 run() 方法體現在繼承 Thread 類中時,可以用 this 指向實際控制運行的 Thread 實例。因此,代碼不需要使用以下控制語句:

    Thread.currenThread().sleep();

    不再使用上面的控制語句,而是可以簡單地使用 Threadsleep() 方法,繼承 Thread 類的方式使代碼變得簡單易讀。

  • 實現 Runnable 接口的優缺點
  • 從面向對象的角度來看,Thread 類是一個虛擬處理機嚴格的封裝,因此只有當處理機模型修改或擴展時,才應該繼承該類。由于 Java 技術只允許單一繼承,因此如果已經繼承了 Thread 類,就不能再繼承其他任何類,這會使用戶只能采用實現 Runnable 接口的方式創建線程。

    Thread和Runnable的區別

    如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable接口的話,則很容易的實現資源共享。

    總結:

    實現Runnable接口比繼承Thread類所具有的優勢:

    1):適合多個相同的程序代碼的線程去處理同一個資源

    2):可以避免java中的單繼承的限制

    3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立

    4):線程池只能放入實現Runable或callable類線程,不能直接放入繼承Thread的類

    提醒一下大家:main方法其實也是一個線程。在java中所以的線程都是同時啟動的,至于什么時候,哪個先執行,完全看誰先得到CPU的資源。

    在java中,每次程序運行至少啟動2個線程。一個是main線程,一個是垃圾收集線程。因為每當使用java命令執行一個類的時候,實際上都會啟動一個JVM,每一個jVM實習在就是在操作系統中啟動了一

    總結

    以上是生活随笔為你收集整理的Java多线程的实现方式-Thread 类,Runnable 接口的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 中文字幕在线观看亚洲 | 美女被娇喘视频 | 国产精品21p| 女人下面流白浆的视频 | 日韩一区二区三区免费在线观看 | 黑人一级视频 | 91精品国产欧美一区二区 | 中文字幕观看视频 | 天天免费看av | 久久久久久国产精品三区 | 国产日本在线观看 | 秋霞综合网 | 欧美精品激情 | 天堂最新资源在线 | 大肉大捧一进一出好爽mba | 黄视频免费观看 | 日本黄网站在线观看 | 久久成| 海角国产乱辈乱精品视频 | 免费看黄网站在线观看 | 黄色性视频| 欧美成人tv | 午夜激情成人 | 丰满多毛的大隂户视频 | 海角社区在线视频播放观看 | 黄色大片黄色大片 | 草久在线 | 成人av电影在线播放 | 99av视频| 疯狂做受xxxx高潮人妖 | 日韩福利视频在线观看 | 亚洲少妇30p| 黄色在线观看网站 | 日韩乱码视频 | 欧美日韩一区电影 | 99久久视频| 国产又爽又黄免费视频 | 黄色欧美在线 | 亚洲高清自拍 | 国产视色| 超碰成人免费电影 | 91久久精品一区二区 | 日韩精品一区二区三区中文在线 | 欧洲三级在线 | 亚洲一区二区三区免费在线观看 | 蜜桃av噜噜一区二区三区麻豆 | 国产123在线 | 亚洲欧美综合精品久久成人 | 国产精品一二三四五 | 一区二区三区日韩欧美 | 国产日韩成人 | 精品日韩在线观看 | 国产一级一区二区 | 成人a级免费视频 | 碧蓝之海动漫在线观看免费高清 | 亚洲狼人综合 | 免费在线观看视频 | 黄色av一区二区三区 | 在线视频 一区二区 | 影音先锋色小姐 | 放几个免费的毛片出来看 | 日韩精品视频在线免费观看 | 在线观看亚洲大片短视频 | 国产农村妇女精品 | 国产精品久久久久久三级 | 中字av在线| 超碰男人的天堂 | 黑人玩弄人妻一区二区三区 | 国产后入清纯学生妹 | 最新国产精品 | 亚洲狠狠婷婷综合久久久久图片 | 亚洲精品久久久久久宅男 | 91久久精品www人人做人人爽 | 性色av蜜臀av| 无码人妻精品一区二 | 国内视频一区二区三区 | 成人久久久久久 | 日本一区二区免费看 | 欧美资源在线观看 | 日韩少妇内射免费播放 | 视色视频 | 台湾佬久久 | 久久一区| 性色浪潮av| 欧美三级特黄 | 亚洲最大福利网 | 国产精品999在线观看 | 精品人伦一区二区三区蜜桃网站 | 精品人妻一区二区三区四区久久 | 精品三级电影 | 国产伦精品视频一区二区三区 | 91微拍| 免费在线观看小视频 | 日批毛片 | 熟妇人妻无码xxx视频 | 四虎在线看片 | 999色综合 | 都市激情麻豆 | 亚洲图色av |