深入理解多執行緒(一)
阿新 • • 發佈:2020-03-13
# 深入理解多執行緒(一)
## 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其實在就是在作業系統中啟動了一個進
>
>