線程的終止
JDK中提供了stop()[不建議使用] 和 interrupt()兩種方式,
同時拋出一個未實現的destroy()[不能使用]方法,
目前stop已經被廢棄了,因爲stop是暴力停止會存在安全問題
正確的結束線程運行的方式:
1、使用interrupt時 配合isInterruptedd()方法,可有效避免線程中斷異常
2、採用標誌位的方式進行判斷,當滿足條件時結束線程的運行,該標誌位需要對被各線程可見(volatile)
package com.milla.study.netbase.expert.concurrent;
import lombok.extern.slf4j.Slf4j;
/**
* @Package: com.milla.study.netbase.expert.concurrent
* @Description: <結束線程[如何優雅的結束線程]>
* @Author: MILLA
* @CreateDate: 2020/4/21 10:51
* @UpdateUser: MILLA
* @UpdateDate: 2020/4/21 10:51
* @UpdateRemark: <>
* @Version: 1.0
*/
@Slf4j
public class InterruptThreadTest {
public static void main(String[] args) throws InterruptedException {
stopThread(); //錯誤的方式
interruptThread();//正確方式1 採用Thread中的interrupt方法
interruptThreadByFlag();//正確方式2 使用標誌位
}
private static void interruptThreadByFlag() throws InterruptedException {
FlagThread flagThread = new FlagThread();
flagThread.start();
Thread.sleep(1500L);
flagThread.interruptThread();//產生的結果:i:1, j:1 不存在線程安全問題
flagThread.printInfo();
}
private static void interruptThread() throws InterruptedException {
StopThread stopThread = new StopThread();
stopThread.start();
Thread.sleep(1000L);
if (stopThread.isInterrupted()) {//配合該線程的狀態判斷使用 可防止線程中斷異常
stopThread.interrupt();//產生的結果:i:1, j:1 不存在線程安全問題
}
stopThread.printInfo();
}
private static void stopThread() throws InterruptedException {
StopThread stopThread = new StopThread();
stopThread.start();
Thread.sleep(1000L);
stopThread.stop();//產生的結果:i:1, j:0 存在線程安全問題 廢棄不用了
stopThread.printInfo();
}
static class FlagThread extends Thread {
private int i, j;
private volatile boolean flag = true;
@Override
public void run() {
while (flag) {
synchronized (this) {
i++;
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
}
}
}
void interruptThread() {//設置標誌位
flag = false;
}
void printInfo() throws InterruptedException {
Thread.sleep(501L);
log.info("產生的結果:i:{}, j:{}", i, j);
}
}
static class StopThread extends Thread {
private int i, j;
@Override
public void run() {
synchronized (this) {
++i;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("報異常麼");
}
++j;
}
}
void printInfo() throws InterruptedException {
Thread.sleep(10L);
log.info("產生的結果:i:{}, j:{}", i, j);
}
}
}