多線程:基礎、Thread類、用法
尚硅谷JavaSE筆記-18
多線程
名詞解釋
英文 | 台灣 | 中國 | 意義 |
---|---|---|---|
Program | 程式 | 程序 | 靜態的程式碼集合 |
Process | 程序(進程) | 進程 | 動態、被執行中且載入記憶體的program,也是 OS 分配資源的最小單位。打開工作管理員看到的就是這個 |
Thread | 執行緒 | 線程 | 一個進程裡至少會有一個線程,表示內部的一條執行路徑。把進程比喻為一個工廠,線程則是工廠裡面的工人,負責任務的實際執行。同一個Process內的Thread使用相同的Memory Space,但這些Thread各自擁有其Stack。換句話說,Thread能透過reference存取到相同的Object,但是local variable卻是各自獨立的。白話:共享方法區跟堆,獨立棧跟計數器 |
Coroutine | 協程 | 協程 | 輕量級的執行緒,由使用者掌控,例如GO的goroutine |
Concurrent | 並行 | 並發 | 一個 CPU 會去做多件事,但是同一個時間點之內只會做一件事,像是早上做 Job1、下午做 Job2、晚上做 Job3不斷的切換,目標是希望能做更多的事 |
Parallel | 平行 | 並行 | 多個 CPU 在同一個時間點內會去做多件事,例如會有三個人同時分別在做 Job1、Job2、Job3 的事情。目標是希望能把事情更快速的做完。 |
需求來源
- 希望同時執行複數的任務,例如一邊執行main方法,GC一邊收垃圾
- 需要等待的狀況,例如等用戶輸入、等IO、等網路連接
Java多線程-方法一
-
造一個類,繼承
Thread
-
重寫此類的
run
方法(將想多線程執行的代碼包進去) -
實例化此類的一個物件
-
透過此物件調用
start();
,此時啟動此線程並且調用他的run()
方法 -
若想再啟動另一條線程,需要再new一個物件,同一物件start多次會報
IllegalThreadStateException
-
舉例:
public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 10000; i++) { if (i % 2 == 0) { System.out.println(i + "新造#####"); } } } } class Test { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { if (i % 2 == 0) { System.out.println(i + "主線程*****"); } } MyThread t1 = new MyThread(); t1.start(); new Thread() { @Override public void run() { for (int i = 0; i < 10000; i++) { if (i % 2 != 0) { System.out.println(i + "匿名類?????"); } } } }.start(); } }
-
也可以透過匿名類的方法
new Thread(){//要執行的代碼}.start();
Thread類的常用方法
start()
:啟動當前線程、調用其run()
currentThread()
:靜態方法,返回當前執行代碼的線程getName()
:獲取當前線程的名字,常與"currentThread().getName()
“這樣連用setName(String)
:設定線程名,在start
前後都有用,也可以用Thread.currentThread().setName("設定主線程名");
yeild()
:靜態方法,釋放當前線程的執行權(但也有可能馬上又搶回),會拋異常join()
:在線程A中調用線程B的join()
,此時A就阻塞,等B完全做完才繼續A。白話:在我的地盤說誰.join
就是我讓誰插隊sleep(毫秒)
:當前線程休息,休息時是阻塞的,會拋異常isAlive()
:判斷當前線程是否存活setDaemon(true)
:轉為守護線程
線程的優先級
- 寫在Thread中的,最小是1,預設是5,最大是10
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
getPriority()
:獲取優先級setPriority(int)
:設置優先級- 但並不是說高優先就一定先執行完,只是機率上的
Java多線程-方法二
-
造一個實現Runnable接口的類
-
實現其中的抽象方法
run()
-
創建實現類的實例物件
-
將此物件作為參數,傳到
Thread
類的構造器中,創建Thread
類的物件 -
通過此
Thread類的物件
調用start()
-
自訂的類是作為形參,想再創一個線程只要
new Thread
即可,舉例:class MyThread2 implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "-" + i); } } } class test { public static void main(String[] args) { MyThread2 m2 = new MyThread2(); Thread t1 = new Thread(m2); t1.start(); Thread t2 = new Thread(m2); t2.start(); } }
-
優勢在於只造了一個類,假如類中有個屬性需要被共用,不管後面造了多少線程都是共用這個變量(而不需使用
static
宣告) -
還一個優勢在於,本身類可能已經有繼承對象了,而我只要實現接口就可以
-
其實方法一點開源碼看也是方法二,實際就優先用方法二吧
小結
- 多線程的核心就是重寫
run()
、調用start()
方法
上次修改於 2021-12-03