一、概述
1、优雅结束线程的生命周期
- interrupt: 设置线程当前中断标记为true,并未真正终止线程
- isInterrupted: 检测当前的中断标记
2、暴力结束线程的生命周期(异步网络请求:请求超时自动断开连接案例,可以自由断开请求)
- 创建父线程,在父线程里创建一个记录时间的线程和真正执行任务的线程(设置为守护线程和join)
- 当超时的时候,记录时间线程调用父线程的interrupt方法, 因为执行任务线程是守护线程,父线程已属于阻塞状态,调用interrupt阻塞的时候,会抛出异常,执行任务线程收到InterruptedException异常时结束线程。
- 调用stop停止线程的时候,调用父线程的interrupt方法,因为执行任务线程是守护线程,父线程已属于阻塞状态,调用interrupt阻塞的时候,会抛出异常,执行任务线程收到InterruptedException异常时结束线程。
二、代码
package com.cfl.thread;
public class Thread6 {
public static void main(String[] args) throws Exception {
// 优雅中断线程
// interruptThread();
// 暴力结束线程
violenceStopThread();
}
/**
* 优雅中断线程
* @throws Exception
*/
public static void interruptThread() throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
while(true) {
if(Thread.currentThread().isInterrupted()) {
System.out.println("线程中断");
break;
}
}
}
});
thread.start();
Thread.sleep(2*1000);
// 中断线程
thread.interrupt();
}
/**
* 暴力结束线程
* @throws Exception
*/
public static void violenceStopThread() throws Exception {
CustomAsynThread thread = new CustomAsynThread(new Runnable() {
public void run() {
try {
// 模拟网络请求
Thread.sleep(15*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 10*1000);
thread.start();
System.out.println("#############");
// thread.stop();
}
// 模拟异步网络请求
static class CustomAsynThread {
private Runnable runnable;
private long timeout; // 超时时间
private boolean isFinish = false; // 是否执行完成
private Thread parentThread; // 执行任务线程的父线程
/**
* @param runnable runnable
* @param timeout 超时时间 毫秒
*/
public CustomAsynThread(Runnable runnable, long timeout) {
this.runnable = runnable;
this.timeout = timeout;
}
// 开始
public void start() {
final long startTime = System.currentTimeMillis();
parentThread = new Thread("父线程") {
@Override
public void run() {
// 计时线程
Thread timeThread = new Thread("计时线程") {
@Override
public void run() {
while (!isFinish) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long ctime = System.currentTimeMillis() - startTime;
System.out.println(ctime);
if(ctime > timeout) {
parentThread.interrupt();
return;
}
}
}
};
timeThread.start();
// 执行任务线程
Thread thread = new Thread(runnable,"执行任务线程");
thread.setDaemon(true); // 设置为守护线程
thread.start();
try {
thread.join();
isFinish = true;
} catch (InterruptedException e) {
isFinish = true;
}
};
};
parentThread.start();
}
// 结束线程
public void stop() {
if(null != parentThread) {
parentThread.interrupt();
}
}
}
// 模拟同步网络请求
static class CustomSynThread {
private Runnable runnable;
private long timeout; // 超时时间
private boolean isFinish = false; // 是否执行完成
private Thread parentThread; // 执行任务线程的父线程
/**
* @param runnable runnable
* @param timeout 超时时间 毫秒
*/
public CustomSynThread(Runnable runnable, long timeout) {
this.runnable = runnable;
this.timeout = timeout;
}
// 开始
public void start() {
final long startTime = System.currentTimeMillis();
parentThread = new Thread("父线程") {
@Override
public void run() {
// 执行任务线程
Thread thread = new Thread(runnable,"执行任务线程");
thread.setDaemon(true); // 设置为守护线程
thread.start();
try {
thread.join();
isFinish = true;
} catch (InterruptedException e) {
isFinish = true;
}
};
};
parentThread.start();
while (!isFinish) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long ctime = System.currentTimeMillis() - startTime;
System.out.println(ctime);
if(ctime > timeout) {
parentThread.interrupt();
break;
}
}
}
// 结束线程
public void stop() {
if(null != parentThread) {
parentThread.interrupt();
}
}
}
}