赞
踩
线程的结束方式一stop:
stop()会释放所有的锁,并且不会做善后工作,会导致其他线程抢到锁,然后读取到中间数据导致数据不一致;所以stop方法废弃了;
- public class TestThread {
-
- @SneakyThrows
- public static void main(String[] s){
-
- Thread t1 = new Thread(()->{
- while (true){
- try {
- System.out.println("go on ...");
- TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
- t1.start();
- TimeUnit.SECONDS.sleep(5);
- t1.stop();
- }
- }
线程的暂停/继续:
暂停的时候是不会释放当前线程所拥有的锁的,假如你没有继续启动resume的话就会导致死锁,所以这两个方法suspend()和resume()废弃了,最好别轻易使用。
- public class TestThread {
-
- @SneakyThrows
- public static void main(String[] s){
-
- Thread t1 = new Thread(()->{
- while (true){
- try {
- System.out.println("go on ...");
- TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
- t1.start();
- TimeUnit.SECONDS.sleep(5);
- t1.suspend();//暂停
- TimeUnit.SECONDS.sleep(3);
- t1.resume();//继续
- }
- }
利用volatile控制线程:
- public class TestThread {
-
- private static volatile boolean runFlag = true;
- @SneakyThrows
- public static void main(String[] s){
-
- Thread t = new Thread(()->{
- long i = 0L;
- while (runFlag){
- i++;
- }
- System.out.println("run end and i="+i);
- //第一次运行 输出:run end and i=3574874025
- //第二次运行 输出:run end and i=3587827843
- });
-
- t.start();
- TimeUnit.SECONDS.sleep(1);
- runFlag = false;
- }
- }
上面的代码是用volatile修饰的变量来判断是否结束线程,是比较优雅的结束线程,但你很难精确的控制线程运行了多少次才结束,所以你只要不依赖线程的中间状态来判断释放结束,volatile还是比较可以的;
利用interrup来结束线程:
- public class TestThread {
-
- @SneakyThrows
- public static void main(String[] s){
-
- Thread t = new Thread(()->{
- while (!Thread.interrupted()){
- }
- System.out.println("t end !");
- });
- t.start();
- TimeUnit.SECONDS.sleep(1);
- t.interrupt();
-
- }
- }
Interrupt设置标志位来打断线程跟volatile类似;interrupt更优雅一点,因为在线程sleep,wait,join的时候interrupt可以捕获异常来做进一步处理(比如做中断线程的处理),但是volatile是判断不了的只能等待、死等,不能跳到下一次循环去读取running变量的值;
利用interrupt()和isInterrupted优雅的结束线程
- public class TestThread {
-
- @SneakyThrows
- public static void main(String[] s){
-
- Thread t = new Thread(()->{
- for (;;){
- if (Thread.currentThread().isInterrupted()){
- System.out.println("Thread is interrupted!");
- System.out.println(Thread.currentThread().isInterrupted());
- break;
- }
- }
- });
- t.start();
- TimeUnit.SECONDS.sleep(2);
- t.interrupt();
-
- }
- }
总结结束线程的方法:
1. 自然结束(能自然结束尽量自然结束)
2. stop() suspend() resume() 等方式结束
3. 通过判断volatile标志来结束
a. 不适合某些场景(比如volatile变量还没同步的时候线程就做了阻塞,则没有办法循环回去)
b. 打断时间不精准,比如一个阻塞集合,容量为1000的时候希望结束线程不要再添加,但是由于volatile同步线程标志位的时间控制的不是很精准,有可能线程还要继续跑一会儿才会停止。
4. 利用interrupt() 和 isInterrupted() 来优雅的控制线程的结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。