Java線程的實現方式詳解(Java基礎)
你好我是辰兮,很高興你能來閱讀,本篇為Java基礎之多線程的實現講解,基礎知識的講解,相關的更多,面試知識已經提前整理好文章可以閱讀學習,希望對初學者有幫助。
線程進程基礎知識參考: 進程線程的面試問題小結
線程面試常見問題參考: Java常見多線程基礎面試問題
文章目錄
一、文章序言
二、繼承Thread類
三、實現Runnable接口
四、兩種實現方式的比較
五、調用start()與run()方法的區別
一、文章序言
創建線程的方式一致為Java面試常見基礎問題,基礎學習中我們常用前兩種方式,下文帶大家用代碼案例進一步了解相關的知識。
常用第二種接口實現,因為實現接口的方式比繼承類的方式更靈活,也能減少程序之間的耦合度。
二、繼承Thread類
繼承自Thread類,Thread類是所有線程類的父類,實現了對線程的抽取和封裝
繼承Thread類創建并啟動多線程的步驟:
①.定義一個類,繼承自Thread類,并重寫該類的run方法,該run方法的方法體就代表了線程需要完成的任務,因此,run方法的方法體被稱為線程執行體
②.創建Thread子類的對象,即創建了子線程
③.用線程對象的start方法來啟動該線程
Demo先創建一個售票線程
package demo1; public class SellTickets extends Thread { //共享數據 static int count = 100; @Override public void run() { //循環售票 while(count > 0) { count--; System.out.println(Thread.currentThread().getName() + "售出了一張票,剩余" + count); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
測試類
import demo1.SellTickets; public class TheadDemo { public static void main(String[] args) { //模擬四個售票員售票 SellTickets s1 = new SellTickets(); SellTickets s2 = new SellTickets(); SellTickets s3 = new SellTickets(); // System.out.println(s1.currentThread().getName()); //這個線程的名稱是main s1.start(); s2.start(); s3.start(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
三、實現Runnable接口
實現Runnable接口創建并啟動多線程的步驟:
a.定義一個Runnable接口的實現類,并重寫該接口中的run方法,該run方法的方法體同樣是該線程的線程執行 體
b.創建Runnable實現類的實例,并以此實例作為Thread的target來創建Thread對象,該Thread對象才是真正的線程對象
c.調用線程對象的start方法來啟動該線程
繼續售票的案例 應該是繼承implement接口,為了簡潔我寫一個里面了
package demo1; public class SellTickets { static int count = 100; static Runnable r = new Runnable() { @Override public void run() { while(count > 0) { count--; System.out.println(Thread.currentThread().getName() + "售出了 一張票,剩余" + count); } } }; public static void main(String[] args) { Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
四、兩種實現方式的比較
①實現Runnable接口的方式
a.線程類只是實現了Runnable接口,還可以繼承其他類【一個類在實現接口的同時還可以繼承另外一個類】
b.可以多個線程共享同一個target對象,所以非常適合多個線程來處理同一份資源的情況
c.弊端:編程稍微復雜,不直觀,如果要訪問當前線程,必須使用Thread.currentThread()
② 繼承Thread類的方式
a.編寫簡單,如果要訪問當前線程,除了可以通過Thread.currentThread()方式之外,還可以使用 super關鍵字
b.弊端:因為線程類已經繼承了Thread類,則不能再繼承其他類【單繼承】 實際上大多數的多線程應用都可以采用實現Runnable接口的方式來實現【推薦使用匿名內部類】java類是單知繼承的
五、調用start()與run()方法的區別
Thread thread = new Thread(); thread.start();
1
2
① - start()方法會新建一個線程,并且讓這個線程執行run()方法。
Thread thread = new Thread(); thread.run();
1
2
② - 調用run()也能正常執行。但是,卻不能新建一個線程,而是在當前線程中調用run()方法,只是作為一個普通的方法調用。
我知道這樣表達有點抽象,所有我截圖了上述案例
建議:不要用run()來開啟新線程,它只會在當前線程中,串行執行run()方法中的代碼。
拓展一下源碼的學習只截取了部分
public synchronized void start() { private native void start0(); /** * If this thread was constructed using a separate * Runnable
run object, then that * Runnable
object's run
method is called; * otherwise, this method does nothing and returns. *
* Subclasses of Thread
should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
在start方法里調用了一次start0方法,這個方法是一個只聲明未定義的方法,并且使用了native關鍵字進行定義native指的是調用本機的原生系統函數。所以,調用start方法,會告訴JVM去分配本機系統的資源,才能實現多線程。
The best investment is to invest in yourself
2020.05.29 記錄辰兮的第70篇博客
Java 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。