在java中如何建立執行緒?以下這篇文章為大家介紹3種創建線程的方式以及差異。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
在java中如果要建立執行緒的話,一般有3種方法:
1、繼承Thread類別;
2、實作Runnable介面;
3、使用Callable和Future建立執行緒。
【推薦學習:java影片教學】
#1. 繼承Thread類別
##繼承Thread類別的話,必須重寫run方法,在run方法中定義需要執行的任務。class MyThread extends Thread{ private static int num = 0; public MyThread(){ num++; } @Override public void run() { System.out.println("主动创建的第"+num+"个线程"); } }建立好了自己的執行緒類別之後,就可以建立執行緒物件了,然後透過start()方法去啟動執行緒。請注意,不是呼叫run()方法啟動線程,run方法中只是定義需要執行的任務,如果呼叫run方法,即相當於在主執行緒中執行run方法,跟普通的方法呼叫沒有任何區別,此時並不會建立一個新的執行緒來執行定義的任務。
public class Test { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); } } class MyThread extends Thread{ private static int num = 0; public MyThread(){ num++; } @Override public void run() { System.out.println("主动创建的第"+num+"个线程"); } }在上面程式碼中,透過呼叫start()方法,就會建立一個新的執行緒了。為了分辨start()方法呼叫和run()方法呼叫的區別,請看下面一個範例:
public class Test { public static void main(String[] args) { System.out.println("主线程ID:"+Thread.currentThread().getId()); MyThread thread1 = new MyThread("thread1"); thread1.start(); MyThread thread2 = new MyThread("thread2"); thread2.run(); } } class MyThread extends Thread{ private String name; public MyThread(String name){ this.name = name; } @Override public void run() { System.out.println("name:"+name+" 子线程ID:"+Thread.currentThread().getId()); } }運行結果: 從輸出結果可以得出以下結論:1)thread1和thread2的執行緒ID不同,thread2和主執行緒ID相同,說明透過run方法呼叫並不會建立新的線程,而是在主執行緒中直接執行run方法,跟普通的方法調用沒有任何區別;2)雖然thread1的start方法調用在thread2的run方法前面調用,但是先輸出的是thread2的run方法調用的相關信息,說明新執行緒建立的過程不會阻塞主執行緒的後續執行。
2. 實作Runnable介面
#在Java中建立執行緒除了繼承Thread類別之外,還可以透過實作Runnable介面來實作類似的功能。實作Runnable介面必須重寫其run方法。 下面是一個例子:public class Test { public static void main(String[] args) { System.out.println("主线程ID:"+Thread.currentThread().getId()); MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); } } class MyRunnable implements Runnable{ public MyRunnable() { } @Override public void run() { System.out.println("子线程ID:"+Thread.currentThread().getId()); } }Runnable的中文意思是“任務”,顧名思義,透過實作Runnable接口,我們定義了一個子任務,然後將子任務交由Thread去執行。注意,這種方式必須將Runnable作為Thread類別的參數,然後透過Thread的start方法來建立一個新執行緒來執行該子任務。如果呼叫Runnable的run方法的話,是不會建立新執行緒的,這根普通的方法呼叫沒有任何差別。 事實上,檢視Thread類別的實作原始碼會發現Thread類別是實作了Runnable介面的。 在Java中,這2種方式都可以用來建立執行緒去執行子任務,具體選擇哪一種方式要看自己的需求。直接繼承Thread類別的話,可能比實作Runnable介面看起來更簡潔,但是由於Java只允許單繼承,所以如果自訂類別需要繼承其他類,則只能選擇實作Runnable介面。
3. 使用Callable和Future建立執行緒
和Runnable介面不一樣,Callable介面提供了一個call()方法作為執行緒執行體,call()方法比run()方法功能強大。 建立並啟動有傳回值的執行緒的步驟如下:public class Main { public static void main(String[] args){ MyThread3 th=new MyThread3(); //使用Lambda表达式创建Callable对象 //使用FutureTask类来包装Callable对象 FutureTask<Integer> future=new FutureTask<Integer>( (Callable<Integer>)()->{ return 5; } ); new Thread(task,"有返回值的线程").start();//实质上还是以Callable对象来创建并启动线程 try{ System.out.println("子线程的返回值:"+future.get());//get()方法会阻塞,直到子线程执行结束才返回 }catch(Exception e){ ex.printStackTrace(); } } }
三種建立執行緒方式比較:
實作Runnable和實作Callable介面的方式基本上相同,不過是後者執行call()方法有回傳值,後者執行緒執行體run()方法無回傳值,因此可以把這兩種方式歸為一種這種方式與繼承Thread類別的方法之間的差別如下:1、執行緒只是實作Runnable或實作Callable接口,還可以繼承其他類別。 2、這種方式下,多個執行緒可以共享一個target對象,非常適合多執行緒處理同一份資源的情況。 3、但是程式設計稍微複雜,如果需要存取當前線程,必須呼叫Thread.currentThread()方法。 4、繼承Thread類別的執行緒類別不能再繼承其他父類別(Java單繼承決定)。PS:一般建議採用實作介面的方式來建立多執行緒
本文來自 java入門 欄目,歡迎學習!
以上是3種Java創建執行緒的方式和區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!