1、线程结束的方法
1). 自然结束(能自然结束就尽量自然结束)
2). stop() suspend() resume() (不推荐)
需要注意的是,直接调用线程的
stop()方法已被废弃,不推荐使用,因为它可能会导致线程不可预料的状态和资源泄露。
3). volatile标志
- 不适合某些场景(比如还没有同步的时候,线程做了阻塞操作,没有办法循环回去)
- 打断时间也不是特别精确,比如一个阻塞容器,容量为5的时候结束生产者, 但是,由于volatile同步线程标志位的时间控制不是很精确,有可能生产者还继续生产一段儿时间
4). interrupt() and isInterrupted(比较优雅)
2、代码示例
1)、首先依然创建一个工具类,控制程序运行时间
public static class SleepHelper {
public static void sleepSeconds(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void sleepMilli(int i) {
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2)、使用stop()结束进程
// =============================================
Thread t1 = new Thread( ()->{
while (true){
System.out.println("go on");
SleepHelper.sleepSeconds(1);
}
});
// 运行t1
t1.start();
// 等待5秒
SleepHelper.sleepSeconds(5);
// 直接结束t2
// 不推荐,因为会破坏程序的一致性,使程序进入死锁
t1.stop();
3)、使用suspend() resume()结束进程
// =============================================
Thread t2 = new Thread(()->{
while (true){
System.out.println("go on");
SleepHelper.sleepSeconds(1);
}
});
// 将t2运行
t2.start();
// 使t2运行5秒
SleepHelper.sleepSeconds(5);
// 再将t2停止
t2.suspend();
SleepHelper.sleepSeconds(3);
// 重新唤醒t2
// 不推荐,因为会破坏程序的一致性,使程序进入死锁
t2.resume();
4)、使用volatile标志
// =============================================
private static volatile boolean running = true;
Thread t3 = new Thread(() -> {
long i = 0L;
// 使用volatile标志位
while (running) {
//wait recv accept
i++;
}
System.out.println("end and i = " + i);
});
t3.start();
SleepHelper.sleepSeconds(1);
running = false;
5)、使用interrupt() and isInterrupted()
// =============================================
Thread t4 = new Thread(() -> {
while (!Thread.interrupted()) {
//sleep wait
}
System.out.println("t1 end!");
});
t4.start();
SleepHelper.sleepSeconds(1);
t4.interrupt();
// =============================================
Thread t5 = new Thread(() -> {
System.out.println("1");
// 只有当线程结束的时候才会运行到下方输出2
LockSupport.park();
System.out.println("2");
});
t5.start();
SleepHelper.sleepSeconds(1);
t5.interrupt();
6)、整体代码
public static class SleepHelper {
public static void sleepSeconds(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void sleepMilli(int i) {
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static volatile boolean running = true;
public static void main(String[] args) throws Exception {
// Solution solution = new Solution();
// =============================================
Thread t1 = new Thread( ()->{
while (true){
System.out.println("go on");
SleepHelper.sleepSeconds(1);
}
});
// 运行t1
t1.start();
// 等待5秒
SleepHelper.sleepSeconds(5);
// 直接结束t2
// 不推荐,因为会破坏程序的一致性,使程序进入死锁
t1.stop();
// =============================================
Thread t2 = new Thread(()->{
while (true){
System.out.println("go on");
SleepHelper.sleepSeconds(1);
}
});
// 将t2运行
t2.start();
// 使t2运行5秒
SleepHelper.sleepSeconds(5);
// 再将t2停止
t2.suspend();
SleepHelper.sleepSeconds(3);
// 重新唤醒t2
// 不推荐,因为会破坏程序的一致性,使程序进入死锁
t2.resume();
// =============================================
Thread t3 = new Thread(() -> {
long i = 0L;
// 使用volatile标志位
while (running) {
//wait recv accept
i++;
}
System.out.println("end and i = " + i);
});
t3.start();
SleepHelper.sleepSeconds(1);
running = false;
// =============================================
Thread t4 = new Thread(() -> {
while (!Thread.interrupted()) {
//sleep wait
}
System.out.println("t1 end!");
});
t4.start();
SleepHelper.sleepSeconds(1);
t4.interrupt();
// =============================================
Thread t5 = new Thread(() -> {
System.out.println("1");
// 只有当线程结束的时候才会运行到下方输出2
LockSupport.park();
System.out.println("2");
});
t5.start();
SleepHelper.sleepSeconds(1);
t5.interrupt();
}