夯實Java基礎,一篇文章全解析線程問題

1. 線程是什么操作系統支持多個應用程序并發執行,每個應用程序至少對應一個進程,彼此之間的操作和數據不受干擾,彼此通信一般采用管道通信、消息隊列、共享內存等方式 。當一個進程需要磁盤IO的時候,CPU就切換到另外的進程,提高了CPU利用率 。
有了進程,為什么還要線程?因為進程的成本太高了 。
啟動新的進程必須分配獨立的內存空間,建立數據表維護它的代碼段、堆棧段和數據段,這是昂貴的多任務工作方式 。線程可以看作輕量化的進程 。線程之間使用相同的地址空間,切換線程的時間遠小于切換進程的時間 。
進程是資源分配的最小單位,而線程是CPU調度的最小單位 。每一個進程中至少有一個線程,同一進程的所有線程共享該進程的所有資源,多個線程可以完成多個不同的任務,也就是我們常說的并發多線程 。
2. 怎樣創建線程創建線程常用的有四種方式,分別是:

  1. 繼承Thread類
  2. 實現Runnable接口
  3. 實現Callable接口
  4. 使用線程池創建
分別看一下怎么具體怎么使用代碼創建的?
2.1 繼承Thread類public class ThreadDemo {public static void main(String[] args) {Thread thread = new MyThread();thread.start(); // 啟動線程}}class MyThread extends Thread {@Overridepublic void run() {System.out.println("關注公眾號:一燈架構");}}輸出結果:
關注公眾號:一燈架構start方法用來啟動線程,只能被調用一次 。
run方法是線程的核心方法 , 業務邏輯都寫在run方法中 。
2.2 實現Runnable接口public class ThreadDemo {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread1 = new Thread(myRunnable, "線程1");Thread thread2 = new Thread(myRunnable, "線程2");thread1.start(); // 啟動線程1thread2.start(); // 啟動線程2}}class MyRunnable implements Runnable {private int count = 5;@Overridepublic void run() {while (count > 0) {System.out.println(Thread.currentThread().getName()+ ",關注公眾號:一燈架構," + count--);}}}輸出結果:
線程2,關注公眾號:一燈架構,4線程1,關注公眾號:一燈架構,5線程1,關注公眾號:一燈架構,2線程1,關注公眾號:一燈架構,1線程2,關注公眾號:一燈架構,3需要把Runnable實例放到Thread類中,才能執行,Thread對象才是真正的線程對象 。
【夯實Java基礎,一篇文章全解析線程問題】使用實現Runnable接口創建線程方式,相比繼承Thread類創建線程,優點是:
  1. 實現的方式沒有類的單繼承性的局限性
  2. 實現的方式更適合來處理多個線程有共享數據的情況
2.3 實現Callable接口public class ThreadTest {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCallable myCallable = new MyCallable();FutureTask<String> futureTask = new FutureTask<String>(myCallable);Thread thread = new Thread(futureTask);thread.start();System.out.println(futureTask.get());}}class MyCallable implements Callable {@Overridepublic String call() throws Exception {return "關注公眾號:一燈架構";}}輸出結果:
關注公眾號:一燈架構實現Callable接口的線程實例對象,配合FutureTask使用,可以接收返回值 。
2.4 使用線程池創建public class ThreadDemo {public static void main(String[] args){ExecutorService executorService = Executors.newFixedThreadPool(10);executorService.execute(() -> System.out.println("關注公眾號:一燈架構"));}}輸出結果:
關注公眾號:一燈架構使用線程池創建線程是工作開發中最常用的方式,優點是:
  1. 線程池幫忙管理對象的創建與銷毀 , 減輕開發者工作量
  2. 線程池幫忙管理任務的調用,資源的創建與分配
  3. 復用線程和對象,提高使用效率
3. 線程的狀態線程共有6種狀態,分別是NEW(初始化)、RUNNABLE(可運行)、WAITING(等待)、TIMED_WAITING(超時等待)、BLOCKED(阻塞)、TERMINATED(終止) 。