Java線程的全方位詳解
❤️大傢好,我是賈斯汀,今天主要聊一聊關於線程的瓜!❤️
先來看一下線程這張圖線程的幾種運行狀態之間運行流程:
看不懂沒關系,慢慢來學習,往下學習來繼續瞭解一下~
什麼是線程?
- 線程是進程的一部分,是程序執行中的一條執行路線;
- 進程就是指程序在其自身地址空間的一次執行活動,是程序獨立運行的基本單位;
- 一個進程可以包含多條線程,一個條線程對應一個進程中的一條執行路線。
線程的幾種創建方式?
主要由四種方式創建線程:
- 方式1:繼承Thread類,重寫run(),無返回值
- 方式2:實現Runnable接口,重寫run(),無返回值
- 方式3:新建FutureTask + 實現Callable接口,重寫call(),有返回值
- 方式4:通過Executors工具類創建線程池 + 調用submit + 重寫Callable接口,重寫call(),有返回值
具體每一種創建方式說明及代碼實現如下:
/** * 創建Thread線程的四種方式之內部類寫法 */ public class NewThread { public static void main(String[] args) throws Exception { //方式1 Thread t1 = new Thread(){ @Override public void run() { System.out.println("方式1:繼承Thread類並重寫run()方法創建線程,無返回值"); } }; t1.start(); Thread.sleep(1000); //方式2 Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("方式2:實現Runnable接口並重寫run()方法創建線程,無返回值"); } }); t2.start(); Thread.sleep(1000); //方式3 FutureTask<String> ft = new FutureTask<>(new Callable<String>() { @Override public String call() throws Exception { String result = "方式3:實現Callable接口並重寫call()方法新建FutureTask對象作為new Thread實例化參數創建線程,有返回值"; return result; } }); Thread t3 = new Thread(ft); t3.start(); System.out.println(ft.get()); //輸出返回值 Thread.sleep(1000); //方式4 ExecutorService pool = Executors.newFixedThreadPool(5); Future<String> future = pool.submit(new Callable<String>(){ @Override public String call() throws Exception { String result = "方式4:通過工具類Executors創建線程池,調用submit新建Future對象並重寫Callable接口重寫call()方法創建線程,有返回值"; return result; } }); pool.shutdown();//關閉線程池 System.out.println(future.get()); //輸出返回值 } }
線程的幾種狀態?
- 新建(new):通過上面介紹的某種方式新建線程即處於新建狀態;
- 就緒(Ready):調用線程的start()方法,首先進入就緒狀態,等待獲取CPU時間;
- 運行(Running):就緒狀態的線程獲取到CPU時間或阻塞狀態的線程恢復都可進入運行狀態;
- 阻塞(Blocked):運行狀態的線程可能因為IO阻塞或在synchronized同步代碼塊中都可進入阻塞狀態;
- 死亡(Dead):正常運行的線程執行結束或就緒狀態的線程直接調用stop()方法就會進入死亡狀態;
- 睡眠(Sleeping):調用sleep方法指定線程睡眠多久,會釋放CPU資源,但不釋放鎖資源,睡眠時間到後會重新進入就緒狀態;
- 等待(Waiting):調用wait會讓線程短暫的處於等待中,會釋放CPU資源,並且釋放鎖資源,進入就緒狀態。
線程相關的核心方法及作用?
- start:調用start()方法底層源碼會判斷線程狀態是否是新建狀態,不是則直接拋異常,並且後續會調用一個native本地方法start0,其底層通過JVM來進行調度最後調用run()方法執行;
- run:調用run()方法,底層會直接進入到重寫的run()方法並執行代碼塊內容;
- sleep:屬於Thread類的一個native本地static靜態方法,可以在任何地方調用sleep(1000)方法,期間會讓當前線程進入睡眠狀態1秒鐘,並讓出CPU資源,但不釋放鎖資源
- wait:屬於Object類的一個方法,隻能在synchronized同步塊中進行調用wait(1000)方法,期間會讓當前線程進入等待狀態1秒鐘,不僅會讓出CPU時間,還釋放並釋放對象鎖資源
- yield:跟sleep一樣,也是Thread類的一個native本地static靜態方法,與sleep的最大區別在於Thread.yield()不需要指定暫停時間,並不會阻塞線程,而是進入就緒狀態,短暫的讓出CPU資源,這份CPU資源可能自己會再次獲取到,這個取決於調度器;
- notify:同wait一樣,也是屬於Object類的一個方法,作用是可以將wait()後等待的線程進行單個喚醒,並進入Read就緒狀態;
- notifyAll:同notify一樣,也是屬於Object類的一個方法,作用將當前對象上的所有等待線程喚醒,並進入Read就緒狀態;
- stop:該方法已被廢棄,不建議使用,該方法的作用是直接將線程結束,進入死亡狀態;
- interrupt:沖斷線程,不保證線程進入死亡、就緒還是繼續運行,不想stop可以直接沖斷一個正在運行的線程。 What’s up!不來個點贊支持一下,這手指是金子做的?
到此這篇關於Java線程的全方位詳解的文章就介紹到這瞭,更多相關Java 線程內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java詳解實現多線程的四種方式總結
- Java使用Runnable和Callable實現多線程的區別詳解
- Java並發教程之Callable和Future接口詳解
- Java多線程 Callable、Future 和FutureTask
- Java多線程之FutureTask的介紹及使用