併發程式設計(一)多執行緒基礎
阿新 • • 發佈:2018-12-30
目錄
併發程式設計(一)多執行緒基礎
1、程序和執行緒的概念
程序:一個應用程式,在程序中會有N多個執行緒,程序是所有執行緒的集合。
執行緒:一條執行路徑。
2、為什麼要使用多執行緒
可以提高程式執行的效率。
3、多執行緒使用的場景
- 給使用者傳送簡訊,防止呼叫簡訊介面耗時過長
- 打包圖片壓縮包
4、多執行緒建立方式
4.1、繼承Thread類
package com.fly.thread_demo.demo_1; /** * 執行緒建立方式一: 繼承Thread類 重寫run方法 */ public class ThreadDemo_1 extends Thread{ @Override public void run() { System.out.println("子執行緒開始"); for (int i = 0; i < 10; i++) { System.out.println("i = " + i); } System.out.println("子執行緒結束"); } public static void main(String[] args) { System.out.println("主執行緒開始"); Thread t1 = new ThreadDemo_1(); t1.start(); System.out.println("主執行緒結束"); } }
4.2、實現Runable介面
package com.fly.thread_demo.demo_1; /** * 執行緒建立方式二: 實現Runnable介面 */ public class ThreadDemo_2 implements Runnable{ @Override public void run() { System.out.println("子執行緒開始"); for (int i = 0; i < 10; i++) { System.out.println("i = " + i); } System.out.println("子執行緒結束"); } public static void main(String[] args) { System.out.println("主執行緒開始"); //在Thread構造方法中 接受一個Runnable介面 Thread t2 = new Thread(new ThreadDemo_2()); t2.start(); System.out.println("主執行緒結束"); } }
4.3、匿名內部類
package com.fly.thread_demo.demo_1;
/**
* 執行緒建立方式三: 匿名類部類
*/
public class ThreadDemo_3 {
public static void main(String[] args) {
System.out.println("主執行緒開始");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子執行緒開始");
for (int i = 0; i < 10; i++) {
System.out.println("i = " + i);
}
System.out.println("子執行緒結束");
}
});
t3.start();
System.out.println("主執行緒結束");
}
}
4.4、執行緒池(後面細說)
5、執行緒的聲生命週期
5.1、新建
new Thread();
5.2、就緒
呼叫start方法後,執行run方法前,等待cpu分配資源
5.3、執行
執行run方法
5.4、阻塞
- 呼叫sleep方法
- 呼叫阻塞式IO
- 呼叫wait方法
5.5、死亡
- run方法執行完畢
- 丟擲異常
- 呼叫stop方法 (容易造成死鎖,不推薦使用)
6、守護執行緒
package com.fly.thread_demo.demo_1;
/**
* 非守護執行緒:主執行緒死亡,不影響 非守護執行緒
* 守護執行緒:主執行緒死亡,守護執行緒同時死亡
*/
public class ThreadDemo_4 implements Runnable{
@Override
public void run() {
System.out.println("子執行緒開始");
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("i = " + i);
}
System.out.println("子執行緒結束");
}
public static void main(String[] args) {
System.out.println("主執行緒開始");
Thread t4 = new Thread(new ThreadDemo_4());
t4.setDaemon(true);//把t4設定為守護執行緒 (可以對比 設定和設定的區別)
t4.start();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主執行緒結束");
}
}
7、join方法
package com.fly.thread_demo.demo_1;
/**
* join :
* 1) 執行緒同步,是並行的執行緒程式設計序列,在A執行緒中呼叫了B執行緒的join()方法時,表示只有當B執行緒執行完畢時,A執行緒才能繼續執行
* 2) 在start方法呼叫之後呼叫
* 3) 實現原理:呼叫執行緒的wait方法來達到同步的目的
*/
public class ThreadDemo_5 {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子執行緒i = " + i);
}
}
});
t1.start();
try {
//(可以對比 設定和設定列印結果的區別)
t1.join(); //在主執行緒中呼叫t1的join方法 表示讓t1先執行完畢再執行主執行緒
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主i = " + i);
}
}
}
package com.fly.thread_demo.demo_1;
/**
* 面試題 現在有3個執行緒 t1 ,t2,t3 如何讓t1 執行完畢 再執行 t2 t2執行完畢再執行t3
*/
public class ThreadDemo_6 {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t1:i = " + i);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
t1.join();//t2 中 呼叫 t1.join() :讓t1執行完畢執行t2
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("t2:i = " + i);
}
}
});
t2.start();
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
t2.join();//t3中 呼叫 t2.join() :讓t2執行完畢執行t3
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("t3:i = " + i);
}
}
});
t3.start();
}
}