華米推出 PumpBeats 血壓監測引擎:測量僅需 30s,後續支援 24 小時連續監測
阿新 • • 發佈:2021-07-13
Java多執行緒
程式、程序和執行緒
一、程式
- 程式是儲存在磁碟上, 包含可執行機器指令和資料的靜態實體。 即程序或者任務是處於活動狀態的計算機程式。
二、程序
-
程序是資源(CPU、記憶體等)分配的基本單位,它是程式執行時的一個例項,即執行中的程式。
-
一個執行著的程式,可能有多個程序。程序在作業系統中執行特定的任務。
-
程式執行時系統就會建立一個程序,併為它分配資源,然後把該程序放入程序就緒佇列,程序排程器選中它的時候就會為它分配CPU時間,程式開始真正執行。
三、 執行緒
- 執行緒就是程式的執行路線,即程序內部的控制序列,或者說是程序的子任務。
- 執行緒,輕量級,不擁有自己獨立的記憶體資源,共享程序的程式碼區、資料區、堆區(注意沒有棧區)、環境變數和命令列引數、檔案描述符、訊號處理函式、當前目錄、使用者ID和組ID等資源。
- 執行緒擁有自己獨立的棧,因此也有自己獨立的區域性變數。
- 一個程序可以同時擁有多個執行緒,即同時被系統排程的多條執行路線,但至少要有一個主執行緒。
總結
- 執行緒就是獨立的執行路徑;
- 在程式執行時,即使沒有自己建立執行緒,後臺也會有多個執行緒,如主執行緒,gc執行緒;
- main()稱之為主執行緒,為系統的入口,用於執行整個程式;
- 在一個程序中,如果開闢了多個執行緒,執行緒的執行由排程器安排排程,排程器是與
- 作業系統緊密相關的,先後順序是不能認為的干預的。
- 對同一份資源操作時,會存在資源搶奪的問題,需要加入併發控制;
- 執行緒會帶來額外的開銷,如cpu排程時間,併發控制開銷。
- 每個執行緒在自己的工作記憶體互動,記憶體控制不當會造成資料不一致
執行緒實現
繼承Thread類
執行緒是程式中執行的執行緒。Java虛擬機器允許應用程式同時執行多個執行執行緒。
每個執行緒都有優先權。 具有較高優先順序的執行緒優先於具有較低優先順序的執行緒執行。 每個執行緒可能也可能不會被標記為守護程序。 當在某個執行緒中執行的程式碼建立一個新的
Thread
物件時,新執行緒的優先順序最初設定為等於建立執行緒的優先順序,並且當且僅當建立執行緒是守護程序時才是守護程序執行緒。當Java虛擬機器啟動時,通常會有一個非守護程序執行緒(通常呼叫某個指定類的名為
main
的方法)。 Java虛擬機器繼續執行執行緒,直到發生以下任一情況:
- 已呼叫類
Runtime
的exit
方法,並且安全管理器已允許執行退出操作。- 通過呼叫
run
方法返回或丟擲超出run
方法傳播的異常,所有非守護程式執行緒的執行緒都已死亡。
建立執行緒方式一:繼承Thread類,重寫run()方法,呼叫start()開啟執行緒
public class MyThread extends Thread{
@Override
public void run() {
//子執行緒方法
for (int i = 0; i < 20; i++) {
System.out.println("我是子執行緒" + i);
}
}
public static void main(String[] args) {
//開啟子執行緒
new MyThread().start();
for (int i = 0; i < 20; i++) {
System.out.println("我是主執行緒" + i);
}
}
}
執行結果
可以發現,主執行緒和子執行緒是”同時“進行的。
Thread類實現了Runnable介面,內部通過靜態代理呼叫了run()方法
實現Runnable介面
public class MyThread implements Runnable{
@Override
public void run() {
//子執行緒方法
for (int i = 0; i < 20; i++) {
System.out.println("我是子執行緒" + i);
}
}
public static void main(String[] args) {
//建立執行緒物件,代理執行緒
new Thread(new MyThread()).start();
for (int i = 0; i < 20; i++) {
System.out.println("我是主執行緒" + i);
}
}
}
使用方法基本和繼承Thread類相同,執行結果也相似。
實現Callable介面
- 實現Callable介面,需要返回值型別
- 重寫call方法,需要丟擲異常
- 建立目標物件
- 建立執行服務: ExecutorService ser = Executors.newFixedThreadPool(1);
- 提交執行: Future<Boolean> result1 = ser. submit(t1);
- 獲取結果: boolean r1 = result1.get()
- 關閉服務: ser. shutdownNow();
示例程式碼
public class MyThread implements Callable<Boolean> {
@Override
public Boolean call() {
//子執行緒方法
System.out.println("執行了子執行緒");
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread t1 = new MyThread();
//建立執行服務
ExecutorService ser = Executors.newFixedThreadPool(1);
//提交執行
Future<Boolean> result1 = ser.submit(t1);
//獲取結果
boolean r1 = result1.get();
//關閉服務
ser. shutdownNow();
}
}