您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關傳統的線程技術中創建線程的方式有哪些的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
傳統的線程技術中有兩種創建線程的方式:一是繼承 Thread
類,并重寫 run()
方法;二是實現 Runnable
接口,覆蓋接口中的 run()
方法,并把 Runnable
接口的實現扔給 Thread
。這兩種方式大部分人可能都知道,但是為什么這樣玩就可以呢?下面我們來詳細分析一下這兩種方法的來龍去脈。
上面我們看到這兩種方式都跟 run()
方法有關,所以我們來看一下 Thread
的源碼中 run()
方法到底都干了什么:
@Override public void run() { if (target != null) { target.run(); } }
我們可以看出, run()
方法中很簡單,只有一個 if
語句,如果 target 不為空就執行 target 的 run()
方法,否則什么也不干,那么這 target 到底是何方神圣呢?我們點擊進去可以看到:
private Runnable target;
原來 target 就是 Runnable 接口,我們再點進 Runnable 看看:
@FunctionalInterface public interface Runnable { public abstract void run(); }
Runnable 中就一個方法,也是 run()
方法!好了,現在再回到 Thread 類的 run()
方法中,如果 target 不為空,即實現了 Runnable 接口,也即實現了 Runnable 中的 run()
方法,那么我們就使用該接口中的 run()
方法;如果 target 為空,即沒有實現 Runnable 接口,那我們什么也不做,即線程創建后立馬就消失了。
所以到這里,大家就明白了為什么創建線程有上面兩種方式了。第一種:你不是要先進行 if
判斷么?我現在不判斷了,我把你的 if
干掉,我在 run()
方法中自己寫代碼,想干啥就干啥,即重寫 Thread 中的 run()
方法,;第二種:你不是要先進行 if
判斷么?行,給你一個 Runnable 接口讓你判斷,但你還是得調用我 Runnable 中的 run()
方法啊,那我重寫我 Runnable 中的 run()
方法不就行了! 知道了來龍去脈后,下面就針對這兩種傳統的方式寫個實例。
只要兩步即可創建并開啟一個線程:
繼承 Thread
類,并實現 run()
方法;
調用 start()
方法開啟線程。
由于只要實現一個 run()
方法即可,所以我們可以使用 Java 中的匿名內部類來實現,如下:
public class TraditionalThread { public static void main(String[] args) { /********** 第一種方法:繼承Thread類,覆寫run()方法 **************/ Thread thread1 = new Thread(){ @Override public void run() { try { Thread.sleep(500);//讓線程休息500毫秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName());//打印出當前線程名 } }; thread1.start();//開啟線程 } }
只要兩步即可創建并開啟一個線程:
實現 Runnable
接口,并實現 run()
方法;
調用 start()
方法開啟線程。
由于只要實現一個 run()
方法即可,所以我們也可以使用 Java 中的匿名內部類來實現,如下:
public class TraditionalThread { public static void main(String[] args) { /********** 第二種方法:實現Runnable接口,扔給Thread **************/ Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } }); thread2.start(); } }
如果有個哥們比較給力,他兩種方式同時使用了,即:既實現了 Thread 類中的 run()
方法,又給 Thread 扔了一個實現了 run()
方法的 Runnable。如下所示:
public class TraditionalThread { public static void main(String[] args) { //這哥們的代碼寫的比較給力 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Runnable:" + Thread.currentThread().getName()); } }){ @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread:" + Thread.currentThread().getName()); } }.start(); } }
現在又會執行哪個呢?我們運行一下上面的程序就會發現,它會打印出 Thread 的信息,所以運行的是 Thread 的 run()
方法,知道結論了,但是為啥呢?
從面向對象的思想去考慮:上面一段代碼其實是新 new 了一個對象(子對象)繼承了 Thread 對象(父對象),在子對象里重寫了父類的 run()
方法,父對象中扔了個 Runnable 進去,父對象中的 run()
方法就是最初的帶有 if
判斷的 run()
方法。
好了,現在執行 start()
后,肯定先在子類中找 run()
方法,找到了,父類的 run()
方法自然就被干掉了,所以會打印出 Thread:,如果我們現在假設子類中沒有重寫 run()
方法,那么必然要去父類找 run()
方法,父類的 run()
方法中就得判斷是否有 Runnable 傳進來,現在有一個,所以執行 Runnable 中的 run()
方法,那么就會打印 Runnable: 出來。
感謝各位的閱讀!關于“傳統的線程技術中創建線程的方式有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。