日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

线程的3种创建方式

發(fā)布時間:2025/3/20 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程的3种创建方式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

所有的線程對象都是Thread類或其子類的實例。

1.通過繼承Thread類創(chuàng)建線程類

1.步驟

  • 定義Thread類的子類FirstThread,并重寫run()方法。run()方法的方法體(線程執(zhí)行體)就是線程要執(zhí)行的任務。
  • 創(chuàng)建FirstThread類的實例。
  • 調用子類實例的star()方法來啟動線程。
  • 2.代碼:

    public class FirstThread extends Thread{ private int i;//重寫run方法,public void run(){for(;i<1000 ;i++){System.out.println(getName()+" "+i);//之所以可以直接調用Therad類的getName()方法,是因為該類繼承了Thread類}}public static void main(String[] args) {for(int i=0;i<100;i++){//獲取當前線程:這里是主線程 System.out.println("當前線程:"+Thread.currentThread().getName()+" "+i);if(i == 20){//啟動第一個線程new FirstThread().start();//啟動第二個線程new FirstThread().start();}}} }

    部分結果:

    Thread-1 731 Thread-0 16 Thread-1 732 Thread-0 17 Thread-1 733 Thread-0 18 Thread-1 734 Thread-0 19

    3.分析結果

    從結果可以看出,第一個線程與第二個線程在交替運行。而且,我們可以發(fā)現(xiàn),線程1的變量從i從731到734連續(xù),而線程2從16到19連續(xù)。這說明,雖然 i 是FirstThread類的實例變量而非局部變量,但因為程序每次創(chuàng)建線程時,都會創(chuàng)建一個對象(new FirstThread),所以線程1與線程2不會共享 i 這個實例變量。
    所以,通過繼承Thread類創(chuàng)建線程類時,多個線程之間無法共享該線程類的實例變量

    2.實現(xiàn)Runnable接口方式創(chuàng)建線程類

    1.步驟

  • 定義Runnable接口實現(xiàn)類SecondThread類,并重寫該接口的run()方法
  • 創(chuàng)建SecondThread的實例st
  • 以st作為target創(chuàng)建Thread對象,該Thread對象才是真正的線程對象啊,只不過該Thread線程,只負責執(zhí)行target里的run()方法。
  • 調用線程對象的start()方法啟動
  • 2.代碼

    public class SecondThread implements Runnable {private int i;@Overridepublic void run() {for(;i<1000;i++){System.out.println(Thread.currentThread().getName()+" "+i);//實現(xiàn)Runnable接口時,只能使用Thread類調用當前線程}}public static void main(String[] args) {SecondThread st = new SecondThread();//創(chuàng)建線程的targetfor(int i=0;i<100;i++){if(i==20){new Thread(st,"線程1").start();new Thread(st, "線程2").start();//兩種方式}}}}

    結果片段1:

    線程1 0 線程2 0 線程2 1 線程2 2 線程2 3 線程2 5 線程2 6

    結果片段2:

    線程2 306 線程2 307 線程1 4 線程1 308 線程1 309

    分析結果

    我們會發(fā)現(xiàn),結果1片段中 i 變量沒有4,而是出現(xiàn)在了片段2中,而且線程2當中沒有i=4這個變量,則線程1就會有,即兩個線程共享 i 這個變量
    所以,程序創(chuàng)建的SecondThread對象只是Thread類構造Thread(Runnable target, String name)中的target,該target可被多個線程共享

    3.使用Callable和Future創(chuàng)建線程

    Callabled接口有點兒像是Runnable接口的增強版,它以call()方法作為線程執(zhí)行體,call()方法比run()方法功能更強大。
    call()方法可以有返回值,可以聲明拋出異常類
    獲取call()方法里的返回值: 通過FutureTask類(實現(xiàn)Future接口)的實例對象的get()方法得到,得到結果類型與創(chuàng)建TutureTask類給的泛型一致。

    1. 步驟

    1、 定義實現(xiàn)Callable接口的實現(xiàn)類,并實現(xiàn)call()方法。注意:Callable有泛型限制,與返回值類型一致。這里是Integer

    public class ThirdThread implements Callable<Integer>{//重寫call()方法}

    2、 再創(chuàng)建Callable實現(xiàn)類的實例tt。

    ThirdThread tt = new ThirdThread();

    3、 使用FutureTask類包裝Callable的實例tt。

    FutureTask<Integer> task = new FutureTask<Integer>(tt);//注意:泛型限制與返回結果一致。

    4、以FutureTask對象(task)作為Thread的target來創(chuàng)建線程,并啟動。

    new Thread(task, "線程").start();

    5、調用FutureTask對象(task)的get()方法獲得返回值

    Integer result = task.get();//會有異常

    2.代碼

    public class ThirdThread implements Callable<Integer>{private int i;@Overridepublic Integer call() throws Exception {for(;i<100;i++){System.out.println(Thread.currentThread().getName()+" "+i);}return i;}public static void main(String[] args) {//創(chuàng)建Callable對象ThirdThread tt = new ThirdThread();FutureTask<Integer> task = new FutureTask<Integer>(tt);for(int i=0;i<1000;i++){System.out.println(Thread.currentThread().getName()+" "+i);if(i == 20){//創(chuàng)建線程 new Thread(task, "線程").start();}}try {//獲取線程返回值Integer result = task.get();System.out.println(result);} catch (InterruptedException e) { e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}}

    3.結果分析

    結果是,只能new一個Thread,即單線程,所以這么寫于多線程是行不通的。需要創(chuàng)建一個能執(zhí)行多個任務的服務。

    4.Future接口控制Callable里任務的幾個方法

  • boolean cancel(boolean mayInterruptIfRunning) : 試圖取消Callable里的任務,即中斷線程。不一定會成功。
  • V get() : 得到Callable任務里call()方法的返回值 。調用該方法將會導致主線程被主阻塞。必須要等到子線程結束后才會得到返回值得到返回值 后,主線程才能繼續(xù)往下執(zhí)行
  • V get(long timeout,TimeUnit unit) : 也是得到返回值,但該方法會讓程序阻塞timeout和unit指定的時間,若指定時間后還沒有返回值 ,則拋出TimeoutException異常。
  • boolean isCanceled() : 如果在任務結束前被取消了,該方法就會返回true.
  • boolean isDone() : 如果Callalbe任務已完成,則返回true。
  • 5.Callable接口方式的多線程示例

    代碼

    public class CallableAndFuture { public static class MyCallableClass implements Callable { private int i = 0; public Integer call() throws Exception { for(;i<1000;i++){System.out.println(Thread.currentThread().getName()+" "+i);}return i; } } public static void main(String[] args) { // 定義3個Callable類型的任務 MyCallableClass task1 = new MyCallableClass(); MyCallableClass task2 = new MyCallableClass(); MyCallableClass task3 = new MyCallableClass(); // 創(chuàng)建一個執(zhí)行任務的服務 ExecutorService es = Executors.newFixedThreadPool(3); try { // 提交并執(zhí)行任務,任務啟動時返回了一個Future對象, // 如果想得到任務執(zhí)行的結果或者是異常可對這個Future對象進行操作 Future future1 = es.submit(task1); // 如果調用get方法,當前線程會等待任務執(zhí)行完畢后才往下執(zhí)行 // System.out.println("task1: " + future1.get()); Future future2 = es.submit(task2); //System.out.println("task2 cancel: " + future2.cancel(true)); // 獲取第三個任務的輸出,因為執(zhí)行第三個任務會引起異常 // 所以下面的語句將引起異常的拋出 Future future3 = es.submit(task3); //System.out.println("task3: " + future3.get()); } catch (Exception e) { System.out.println(e.toString()); } // 停止任務執(zhí)行服務 es.shutdownNow(); } }

    結果片段

    pool-1-thread-2 502 pool-1-thread-3 867 pool-1-thread-2 503 pool-1-thread-3 868 pool-1-thread-2 504 pool-1-thread-3 869 pool-1-thread-2 505 pool-1-thread-3 870 pool-1-thread-2 506 pool-1-thread-3 871 pool-1-thread-2 507

    結果分析
    只要不調用get()方法,就不會阻塞,多個線程之間會交替執(zhí)行;從序號可看出,每個線程的都是連續(xù)的,所以每個線程之間不共享實例變量 i ,這跟Thread方式是一樣的。原因是每個線程我們都new了一個task的。

    4.三種創(chuàng)建方式區(qū)別

    首先三種方式都可以創(chuàng)建多線程。
    Thread方式和Callable方式不能共享實例變量;而Runnalbe方式可共享,因為能共享target。
    因為通過實現(xiàn)Runnable接口與Callable接口類似,只是Callable接口方式的call()方法有返回值和可聲明拋出異常,所以我們將這兩種方式統(tǒng)稱為RC方式。通過繼承Thread類方式稱為T方式。

    1. RC方式優(yōu)缺點:

  • 優(yōu)點
  • 還可以繼承其他類。
  • 多個線程可共享一個target對象。適用于多個線程處理同一份資源的情況。
  • 缺點
    編程稍稍復雜些。
  • 2. T方式優(yōu)缺點:

  • 優(yōu)點
    編程簡單。

  • 缺點
    因為單繼承的限制,不能再繼承其他類了。

  • 綜上分析:最好采用RC方式。

    總結

    以上是生活随笔為你收集整理的线程的3种创建方式的全部內容,希望文章能夠幫你解決所遇到的問題。

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