【为何不建议使用stop呢?】:
因为很容易产生数据不一致的问题;
stop方法不管你线程处于什么状态,如果持有很多把锁,它会二话不说释放所有的锁,并且不会做善后的工作。原先的锁如果是为了数据的一致性,那么使用stop有可能就会打破数据的一致性。
public class T01_Stop {public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {System.out.println("go on");SleepHelper.sleepSeconds(1);}});t.start();SleepHelper.sleepSeconds(5);t.stop(); //不建议大家使用。}
}
【这两个方法被废掉的原因】:
原因和stop非常的类似 , 万一暂停的瞬间持有一把锁 , 这一把锁是不会被释放的,如果你忘记了恢复,那么就缔造出了一把《永恒的锁》。所以也是会产生数据不一致的问题的。
public class T02_Suspend_Resume {public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {System.out.println("go on");SleepHelper.sleepSeconds(1);}});t.start();SleepHelper.sleepSeconds(5);t.suspend(); //暂停;SleepHelper.sleepSeconds(3);t.resume(); //恢复执行。}
}
【不太适合的情况】:
循环中有个数统计的计数器。
循环中有wait、recv、accept等方法,wait会阻塞住,不能进行下一次循环,也无法结束。
【适合的情况】:
不太依赖中间的状态——如上传数据,多上传一些 / 少上传一些 都不影响的这种情况。
public class T03_VolatileFlag {private static volatile boolean running = true;public static void main(String[] args) {Thread t = new Thread(() -> {long i = 0L;while (running) {//wait recv accepti++;}System.out.println("end and i = " + i); //4168806262 4163032200});t.start();SleepHelper.sleepSeconds(1);running = false;}
}
//interrupt比volatile更加优雅一些 , 因为如果是volatile的话 , 中间有一些wait / sleep 的话 , 你是停不了的 , 无法跳到下一次循环。但如果是interrupt的话,你只要在sleep / wait 里面处理 InterruptedException 也可以正确的结束这个线程。
【仍有缺点】:
10个元素的容器 , 精确到第5个 , 这个也是无法达到的!!!
【这种情况如何正常结束呢?】:
必须生产者Thread和外面打断它的Thread , 两者配合才可以。
【其他方法】:
内部线程进行定时的检查 , 每隔多长时间检查一次标志位 , 每经过一次循环检查一次标志位。
/*** interrupt是设定标志位*/
public class T04_Interrupt_and_NormalThread {public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.interrupted()) { //只要标记位没被设置,我就一直循环~ ~ ~//sleep wait}System.out.println("t1 end!");});t.start();SleepHelper.sleepSeconds(3);t.interrupt();}
}
public class T05_InterruptAndPark {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println("1");LockSupport.park();System.out.println("2");});t.start();SleepHelper.sleepSeconds(2);t.interrupt();}
}
【volatile 和 interrupt】:
总之,你不依赖于中间精确的次数和精确的时间的话 , 它俩都行。
【结束线程的方法】: