学海无涯:
java 多线程基础知识:
stop()
Thread 的stop()为什么不建议使用,因为stop会导致线程的资源不被正确的释放,太过于强硬,
interrupt()
对线程发起一个中断,并不是真正的中断线程,其实是修改线程的中断标志位的值,不代表当前线程立即中断。
源码
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
interrupted()
此方法是Thread的静态方法,调用后,会重置当前线程的中断标识位,重置标志位
isInterrupted()
此方法是Thread的public方法,调用interrupt(),并不会
public boolean isInterrupted() {
return isInterrupted(false);
}
jdk 线程是协作的,不是抢占
如何安全的退出线程
不建议使用一个boolean标识放在while循环中,去判断是否中断线程,原因:当前线程在执行中如果进入sleep或者wait,当前线程被挂起的时候,完全不会去检测这个标识的,不被唤醒,那么不能正确的跳出,正确的方法应该是使用Thread的interrupted或静态的interrupted来作为while的条件,因为,会被try-catch感知到中断异常,在catch中,手动再次调用interrupted(),我们就可以真正去中断线程,因为捕获异常后,中断标志位会被重置成false(如下源码)
public static native void sleep(long millis) throws InterruptedException;
public final void wait() throws InterruptedException {
wait(0);
}
正确的方式是使用Thread的interrupted或静态的interrupted来作为while的条件,在跳出循环,在while循环中使用,
private void testInterrupt(){
Thread thread = new MyThread();
thread.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
public class MyThread extends Thread{
@Override
public void run() {
super.run();
System.out.println(Thread.currentThread().getName() + " --" + Thread.currentThread().isInterrupted());
while (!Thread.currentThread().isInterrupted()){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + " --" + Thread.currentThread().isInterrupted());
interrupt();
}
}
System.out.println(Thread.currentThread().getName() + " --" + Thread.currentThread().isInterrupted());
}
}