java 多執行緒(關於Thread的講解)
學習來源於b站 https://www.bilibili.com/video/av82219418
自己僅作 java 多執行緒的記錄,看視訊主要還是看書看不下去了…
然後推薦大家看看《JAVA併發程式設計實踐》
Thread 介紹
Thread 生命週期圖
- java 應用程式的main函式是一個執行緒,是被jvm啟動時呼叫,執行緒的名字叫main
- 實現一個執行緒,必須建立Thread 例項,override run方法,並且呼叫start方法
- 在JVM啟動後,實際上有多個執行緒,但是至少有一個非守護執行緒
- 當你呼叫一個執行緒start方法的時候,此時至少有兩個執行緒,一個是呼叫你的執行緒,還有一個執行run方法的執行緒
下面程式碼觀察,Thread 執行緒用 run
執行和 start
執行的區別
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("start:"+Thread.currentThread().getName()); // 當前執行緒名
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("run:"+Thread.currentThread().getName()); // main 執行緒
}
}).run(); // 呼叫run方法,僅僅是例項物件呼叫
}
Thread 構造方法介紹
- 建立執行緒物件Thread,預設有一個執行緒名,以Thread-開頭,以0開始計數,具體實現參考以下原始碼
public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); }
- 如果構造執行緒物件時,未傳入ThreadGroup,Thread 會預設獲取父執行緒的ThreadGroup 作為該執行緒的ThreadGroup , 此時子執行緒和父執行緒在同一個ThreadGroup中,參考以下原始碼
/* If the security doesn't have a strong opinion of the matter use the parent thread group. */ if (g == null) { g = parent.getThreadGroup(); }
- 構造Thread 的時候傳入stacksize 代表著該執行緒佔用stack大小,如果沒有指定stacksize 的大小,預設是0,0代表著會忽略該引數,該引數會被JNI函式去使用。需注意:該引數有一些平臺有效,有些平臺無效。
Daemon 執行緒
守護執行緒
Thread thread = new Thread(() -> {
Thread innerThread = new Thread(() -> {
while(true){
System.out.println("do something...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
innerThread.setDaemon(true); // 設定為守護執行緒
innerThread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
作用:當你執行緒呼叫其他執行緒的時候,你的執行緒結束時,設定為守護執行緒會隨著外面的執行緒而結束。
join 方法
等待當前執行緒執行完後,主執行緒繼續執行的意思。
public static void testJoin() throws InterruptedException {
Thread t = new Thread(new Runnable() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(10000);
}
});
t.start();
t.join();
System.out.println("finish...");
}
上述例子,如果不新增t.join();
的話,裡面會把輸出語句列印出來,但是新增後,等上面的執行緒執行完畢後,在執行主執行緒。當我們統計其他執行緒的時候,就需要用到join。
執行緒結束
方式1,利用標記的方式
public class ThreadStop extends Thread {
private volatile boolean start = true;
@Override
public void run() {
while(start){
// TODO
}
}
public void shutdown(){
this.start = false;
}
public static void main(String[] args) throws InterruptedException {
ThreadStop threadStop = new ThreadStop();
threadStop.start();
Thread.sleep(1000);
threadStop.shutdown();
}
}
方式2:利用interrupt方法
public class ThreadStop extends Thread {
@Override
public void run() {
while(true){
if(Thread.interrupted()){
break; // return
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadStop threadStop = new ThreadStop();
threadStop.start();
Thread.sleep(1000);
threadStop.interrupt();
}
}
暴力解決執行緒
無論標記,還是打斷的方式,都需要在某一處判斷,但是多數時候,block的狀態,我們才想結束;
而jdk 提供的stop()方法已經過期了。
之前守護執行緒提起過,如果我們主執行緒被結束的話,守護程式也是被jvm關閉的。
/**
* @Author: shengjm
* @Date: 2020/2/5 15:48
* @Description: 讓傳入的執行緒成為守護執行緒,這樣關閉執行緒的時候,關閉守護執行緒
*/
public class ThreadCloseForce {
private boolean finished = false;
private Thread executeThread;
public void execute(Runnable task){
executeThread = new Thread(new Runnable() {
@Override
public void run() {
Thread runner = new Thread(task);
runner.setDaemon(true);
runner.start();
try {
runner.join();
finished = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
executeThread.start();
}
public void shutdown(long mills){
long currentTime = System.currentTimeMillis();
while(!finished){
if(System.currentTimeMillis() - currentTime > mills){
System.out.println("超時啦~");
executeThread.interrupt();
break;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
finished = false;
}
public static void main(String[] args) {
ThreadCloseForce threadCloseForce = new ThreadCloseForce();
long start = System.currentTimeMillis();
threadCloseForce.execute(()->{
// while(true){
// //TODO
// }
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadCloseForce.shutdown(10000);
long end = System.currentTimeMillis();
System.out.println("總共消耗時間"+(end-start));
}
}
相關文章
- Java多執行緒Thread類使用Java執行緒thread
- Java多執行緒(二):Thread類Java執行緒thread
- java多執行緒之Thread類Java執行緒thread
- Thread執行緒知識點講解thread執行緒
- Java多執行緒之Thread原始碼分析Java執行緒thread原始碼
- Java 中的執行緒 threadJava執行緒thread
- Android/java 多執行緒(二)-Thread的好兄弟HandlAndroidJava執行緒thread
- Java實現多執行緒詳解一 ( 繼承Thread方式 )Java執行緒繼承thread
- java多執行緒程式設計,Thread,Runnable,Future相關知識Java執行緒程式設計thread
- Java 多執行緒(Java.Thread)------ 執行緒協作(生產者消費者模式)Java執行緒thread模式
- 關於Java併發多執行緒的一點思考Java執行緒
- Java多執行緒詳解Java執行緒
- Thread(執行緒)thread執行緒
- 多執行緒系列(二)之Thread類執行緒thread
- Java中的多執行緒詳解Java執行緒
- Android/java 多執行緒(一)-Thread的使用以及原始碼分析AndroidJava執行緒thread原始碼
- Java之實現多執行緒的方式一 :繼承Thread類Java執行緒繼承thread
- Java多執行緒詳解——一篇文章搞懂Java多執行緒Java執行緒
- Swift多執行緒:使用Thread進行多執行緒間通訊,協調子執行緒任務Swift執行緒thread
- Java多執行緒-執行緒中止Java執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- JAVA多執行緒詳解(一)Java執行緒
- Java 多執行緒詳解(一)Java執行緒
- Java多執行緒超詳解Java執行緒
- Java多執行緒相關知識Java執行緒
- JAVA多執行緒詳解(3)執行緒同步和鎖Java執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- 詳解JAVA執行緒問題診斷工具Thread DumpJava執行緒thread
- java多執行緒Java執行緒
- Java - 多執行緒Java執行緒
- java——多執行緒Java執行緒
- java 多執行緒Java執行緒
- java多執行緒之執行緒的基本使用Java執行緒
- 【Java】【多執行緒】執行緒的生命週期Java執行緒
- Java多執行緒-執行緒狀態Java執行緒
- Java多執行緒-執行緒通訊Java執行緒