深入探究Java線程的創(chuàng)建與構(gòu)造方法
一、創(chuàng)建線程
啟動線程—start 方法
通過覆寫 run 方法創(chuàng)建?個線程對象,但線程對象被創(chuàng)建出來并不意味著線程就開始運行了
- 覆寫run方法是給線程指令清單
- 但是start方法,則是讓線程去真正的執(zhí)行
方法一
繼承Thread類
/** * 繼承Thread創(chuàng)建線程 */ class MyThread1 extends Thread{ @Override public void run() { //業(yè)務(wù)代碼 Thread thread = Thread.currentThread(); System.out.println("名稱:" + thread.getName()); } } public class ThreadDemo1 { public static void main(String[] args) { //獲得當前的線程 Thread mainThread = Thread.currentThread(); System.out.println("名稱:" + mainThread.getName()); Thread thread = new MyThread1(); //開啟線程 thread.start(); } }
因為 Java 是單繼承,繼承了 Thread 就不能繼承其他類了,然而 Java 可以實現(xiàn)多個接口,于是有了下?種方式
方法二
實現(xiàn)Runnable接口
/** * 使用Runnable接口創(chuàng)建線程 */ class MyThread2 implements Runnable{ @Override public void run() { Thread thread = Thread.currentThread();//得到當前線程 System.out.println("名稱:" + thread.getName()); } } public class ThreadDemo2 { public static void main(String[] args) { MyThread2 myThread2 = new MyThread2(); //創(chuàng)建線程 Thread thread = new Thread(myThread2); //啟動線程 thread.start(); } }
方法三
繼承Thread類使用匿名內(nèi)部類
/** * 繼承Thread使用匿名內(nèi)部類創(chuàng)建 */ public class ThreadDemo4 { public static void main(String[] args) { Thread thread = new Thread(){ @Override public void run() { // 業(yè)務(wù)代碼 Thread thread2 = Thread.currentThread(); System.out.println("名稱" + thread2.getName()); } }; //開始線程 thread.start(); } }
方法四
實現(xiàn)Runnable接口,使用匿名內(nèi)部類
/** * runnable使用匿名內(nèi)部類創(chuàng)建 */ public class ThreadDemo3 { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { //具體業(yè)務(wù) Thread thread1 = Thread.currentThread(); System.out.println("名稱:" + thread1.getName()); } }); //開啟線程 thread.start(); } }
方法五
使用lambda表達式
/** * 使用lambda表達式 */ public class ThreadDemo5 { public static void main(String[] args) { //創(chuàng)建線程 Thread thread = new Thread(()->{ //業(yè)務(wù)代碼 Thread thread3 = Thread.currentThread(); System.out.println("名稱" + thread3.getName()); }); //啟動線程 thread.start(); } }
方法六
帶返回值的 Callable
import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 使用callable創(chuàng)建線程 */ public class ThreadDemo6 { public static void main(String[] args)throws ExecutionException, InterruptedException { // 創(chuàng)建 Callable 實例 MyCallable callable = new MyCallable(); // 用于接收 Callable 結(jié)果的對象 FutureTask<Integer> futureTask = new FutureTask<Integer>(callable); // 創(chuàng)建新線程 Thread thread = new Thread(futureTask); // 啟動線程 thread.start(); // 接收新線程執(zhí)行的結(jié)果 int result = futureTask.get(); System.out.println(Thread.currentThread().getName() + "——新線程返回的結(jié)果為:" + result); } } /** * Callable<V> 泛型里面可以是任意數(shù)據(jù)類型 */ class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { // 生成隨機數(shù):0-9 int randomNum = new Random().nextInt(10); System.out.println(Thread.currentThread().getName() + "——隨機數(shù):" + randomNum); return randomNum; } }
在創(chuàng)建線程時, 如果是 JDK 1.8 以上版本,在不需要獲得線程執(zhí)行結(jié)果的情況下,推薦使用Lambda 方式來創(chuàng)建線程,因為它的寫法足夠簡潔;如果想要獲取線程執(zhí)行結(jié)果,可使用FutureTask + Callable 的方式來實現(xiàn)
二、run方法和start方法的區(qū)別
run 方法和 start 方法的主要區(qū)別如下:
①方法性質(zhì)不同
run 是一個普通方法,而 start 是開啟新線程的方法。
②執(zhí)行速度不同
調(diào)用 run 方法會立即執(zhí)行任務(wù),調(diào)用 start 方法是將線程的狀態(tài)改為就緒狀態(tài),不會立即執(zhí)行。
③調(diào)用次數(shù)不同
run 方法可以被重復(fù)調(diào)用,而 start 方法只能被調(diào)用一次。start 方法之所以不能被重復(fù)調(diào)用的原因是,線程的狀態(tài)是不可逆的,Thread 在 start 的實現(xiàn)源碼中做了判斷,如果線程不是新建狀態(tài) NEW,則會拋出非法線程狀態(tài)異常IllegalThreadStateException
public static void main(String[] args) { // 創(chuàng)建線程一 Thread thread = new Thread(new Runnable() { @Override public void run() { // 獲取到當前執(zhí)行的線程 Thread currThread = Thread.currentThread(); System.out.println("執(zhí)行線程一,線程名:" + currThread.getName()); } }); // 調(diào)用 run 方法 thread.run(); // 多次調(diào)用 run 方法 thread.run(); // 創(chuàng)建線程二 Thread thread2 = new Thread(new Runnable() { @Override public void run() { // 獲取到當前執(zhí)行的線程 Thread currThread = Thread.currentThread(); System.out.println("執(zhí)行線程二,線程名:" + currThread.getName()); } }); // 調(diào)用 start 方法 thread2.start(); // 多次調(diào)用 start 方法 thread2.start(); }
從上述結(jié)果可以看出,run 方法多次調(diào)用可用正常執(zhí)行,而第二次調(diào)用 start 方法時程序就報錯了,提示“IllegalThreadStateException”非法線程狀態(tài)異常
總結(jié)
方法性質(zhì)不同:run 是一個普通方法,而 start 是開啟新線程的方法。
執(zhí)行速度不同:調(diào)用 run 方法會立即執(zhí)行任務(wù),調(diào)用 start 方法是將線程的狀態(tài)改為就緒狀態(tài),不會立即執(zhí)行。
調(diào)用次數(shù)不同:run 方法可以被重復(fù)調(diào)用,而 start 方法只能被調(diào)用一次。
三、線程的構(gòu)造方法
1、Thread()創(chuàng)建線程
Thread t1 = new Thread();
2、Thread(Runnable target) 創(chuàng)建線程
Thread t2 = new Thread(new MyRunnable());
3、Thread(String name)創(chuàng)建線程且命名
/** * 創(chuàng)建線程,構(gòu)造方法設(shè)置線程名稱 */ public class ThreadDemo9 { public static void main(String[] args) { //構(gòu)造方法設(shè)置名稱 Thread thread = new Thread("線程1"){ @Override public void run() { //休眠線程 try { Thread.sleep(1000*60*60); } catch (InterruptedException e) { e.printStackTrace(); } } }; thread.start(); } }
4、Thread(Runnable target, String name),用Runnable 對象創(chuàng)建線程對象,并命名
/** * 創(chuàng)建線程,并設(shè)置名稱 */ public class ThreadDemo10 { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000*60*60); } catch (InterruptedException e) { e.printStackTrace(); } } },"Runable-Thread"); thread.start(); } }
到此這篇關(guān)于深入探究Java線程的創(chuàng)建與構(gòu)造方法的文章就介紹到這了,更多相關(guān)Java線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java中有關(guān)構(gòu)造方法中的輸出
- Java基礎(chǔ)學習之構(gòu)造方法詳解
- java線程組構(gòu)造方法源碼解析
- 詳解Java的構(gòu)造方法及類的初始化
- java中構(gòu)造方法及this關(guān)鍵字的用法實例詳解(超詳細)
- Java字節(jié)緩存流的構(gòu)造方法之文件IO流
- Java構(gòu)造方法和方法重載詳解
- Java 構(gòu)造方法的使用詳解
- Java構(gòu)造方法 super 及自定義異常throw合集詳解用法
- java構(gòu)造器 默認構(gòu)造方法及參數(shù)化構(gòu)造方法
- Java構(gòu)造方法有什么作用?
相關(guān)文章
Spring Boot Actuator監(jiān)控的簡單使用方法示例代碼詳解
這篇文章主要介紹了Spring Boot Actuator監(jiān)控的簡單使用,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06Springboot項目出現(xiàn)java.lang.ArrayStoreException的異常分析
這篇文章介紹了Springboot項目出現(xiàn)java.lang.ArrayStoreException的異常分析,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-12-12Eclipse創(chuàng)建java程序可執(zhí)行jar包教程
這篇文章主要為大家分享了Eclipse創(chuàng)建java程序可執(zhí)行jar包教程,具有一定的實用性和參考價值,感興趣的小伙伴們可以參考一下2016-05-05JAVA使用commos-fileupload實現(xiàn)文件上傳與下載實例解析
這篇文章主要介紹了JAVA使用commos-fileupload實現(xiàn)文件上傳與下載的相關(guān)資料,需要的朋友可以參考下2016-02-02