1. 程式人生 > >深入理解多執行緒(一)

深入理解多執行緒(一)

# 深入理解多執行緒(一) ## 1.多執行緒的原理 ### 1.1 程式碼展示多執行緒 為了演示多執行緒,我們用一個程式碼來展示多執行緒的效果: ```java public class App { public static void main(String[] args) throws InterruptedException { //子執行緒 new Thread(() -> { for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName()+":小強"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); //主執行緒 for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName()+":旺財"); Thread.sleep(100); } } } ``` 流程圖: ![](https://img2020.cnblogs.com/blog/1870574/202003/1870574-20200311165955007-621405094.png) 程式啟動執行main時候,java虛擬機器啟動一個程序,主執行緒main在main()呼叫時候被建立。隨著呼叫Thread的物件的start方法,另外一個新的執行緒也啟動了,這樣,整個應用就在多執行緒下執行。 通過這張圖我們可以很清晰的看到多執行緒的執行流程。 ### 1.2 圖解多執行緒時記憶體狀態圖 多執行緒執行時,在棧記憶體中,其實**每一個執行執行緒都有一片自己所屬的棧記憶體空間**。進行方法的壓棧和彈棧。 ![](https://img2020.cnblogs.com/blog/1870574/202003/1870574-20200311170102808-106230865.png) > jvm虛擬機器中,堆中放的是物件和資料,棧中放的是方法,方法區中放的是class類檔案 ## 2. 建立執行緒的兩種方法 ### 2.1 繼承Thread類 ```java public class MyThread extends Thread{ public MyThread(String name){ super(name); } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("小強"); } } } //呼叫 new MyThread("myThread").start ``` ### 2.2 實現Runable介面 ```java public class MyThread implements Runnable{ @Override public void run() { System.out.println("myThread"); } } //呼叫 Thread thread=new Thread(new MyThread()); thread.start() ``` 我們更傾向於使用匿名內部類: ```java new Thread(() -> { for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName()+":小強"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); ``` 通過實現Runnable介面,使得該類有了多執行緒類的特徵。run()方法是多執行緒程式的一個執行目標。所有的多執行緒 程式碼都在run方法裡面。**Thread類實際上也是實現了Runnable介面的類**。 在啟動多執行緒的時候,需要先通過Thread類的構造方法Thread(Runnable target) 構造出物件,然後呼叫Thread 物件的start()方法來執行多執行緒程式碼。 實際上所有的多執行緒程式碼都是通過執行Thread的start()方法來執行的。因此,不管是繼承Thread類還是實現 Runnable介面來實現多執行緒,最終還是通過Thread的物件的API來控制執行緒的 ### 2.3 兩者的優劣 如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable介面的話,則很容易的實現資源共享。 **總結:** **實現Runnable介面**比**繼承Thread**類所具有的優勢: 1. 適合多個相同的程式程式碼的執行緒去共享同一個資源。 2. 可以避免java中的單繼承的侷限性。 3. 增加程式的健壯性,實現解耦操作,程式碼可以被多個執行緒共享,程式碼和執行緒獨立。 4. 執行緒池只能放入實現Runable或Callable類執行緒,不能直接放入繼承Thread的類。 > 擴充:在java中,每次程式執行至少啟動2個執行緒。一個是main執行緒,一個是垃圾收集執行緒。因為每當使用 > > java命令執行一個類的時候,實際上都會啟動一個JVM,每一個JVM其實在就是在作業系統中啟動了一個進 > >