1-调用stop方法,该方法不建议使用,这种方法会强制关闭线程,不会管线程中的数据状态,也不会去处理数据的中间态,造成数据的不一致。
public static void main(String[] args) {
Thread thread = new Thread(()->{
while (true){
System.out.println("go on ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
thread.stop();
}
2-suspend方法(暂停).resume方法(恢复),该方法也不建议使用。对于waiting状态和block状态的线程是无法处理的。当缺少了resume方法的调用的时候,会一直持有锁,不会释放锁。导致死锁问题.同时也会出现与stop方法相同的问题,出现数据的不一致。
public static void main(String[] args) {
Thread thread = new Thread(()->{
while (true){
System.out.println("go on ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
//暂停
thread.suspend();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
//重启
thread.resume();
}
3-使用volatile修饰变量控制,无法精细化控制,当状态变成了结束的时候,上一个线程检测到结束的标记,结束线程时,无法保证线程执行的方法内,数字的值与外部预判的值一致,也就是说打断时间没有办法精细化控制。
public volatile static Boolean flag = true;
public static void main(String[] args) {
Thread thread = new Thread(()->{
long i =0;
while (flag){
i++;
}
System.out.println("i:= " + i);
});
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
flag = false;
}
4-interrupt()and isInterrupted(比较优雅)-通过判断线程的interrpute状态来判断线程的结束,同时也能通过捕获对应的wait和block的状态所抛出的异常,来处理对应状态下的业务逻辑。
public static void main(String[] args) {
Thread thread = new Thread(()->{
long i =0;
while (!Thread.interrupted()){
i++;
}
System.out.println("i:=" + i);
});
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
总结:关闭线程的方法有三大类 1.自然结束(能自然结束的尽量自然结束) 2.使用stop(),suspend(),resume()方法 3.使用volatile标志位 3.1有些场景不符合使用(存在线程阻塞的情况,导致无法进入下一次的循环判断标志位) 3.2无法精确控制,当循环内执行累加操作时,外部控制的标志位的变更无法准确的停止到指定数据的累加 4.使用interrupted()和interrupt()方法是比较优雅的。 通过线程本身的状态位去结束,同时也能解决标志的阻塞问题,通过捕获对应的异常做相应的处理即可。