如何正确的暂停线程

对于启动一个线程都知道如何启动,但是对于中断一个线程呢,例如在线程持续处理业务时,由于处理逻辑中有访问接口异常,在接口恢复后再对数据进行处理,以免出现大量错误数据,那么采用什么方式进行中断,需要谨慎的选择,Thread的api中提供了几个方式进行中断,stop()、suspend()都已经标记为过时,因为存在安全问题,再这里主要对两种中断方式做讲解。

方式说明
设置标志在线程中设置标志位来判断是否暂停
interrupt()中断线程,这时只是标记要中断,实际什么时间暂停将由计算机决定

设置标志方式

首先创建一个线程类并且声明volatile的Boolean的标志。

/**
 * @author : Erick
 * @version : 1.0
 * @Description :
 * @time :2019-4-19
 */
public class JmsThread implements Runnable {
	//volatile可见性,变量变更始终从主存中获取最新值,而不存在延迟。
    volatile Boolean keepRunning = true;

    @Override
    public void run() {
        while (true){
        	//判断标志是否为true
            if (keepRunning){
                System.out.println("当前运行线程为:" +Thread.currentThread().getName());
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

编写测试类

import java.util.HashMap;
import java.util.Map;

/**
 * @author : Erick
 * @version : 1.0
 * @Description :
 * @time :2019-4-19
 */
public class TestJms {
    static Map<Integer , Runnable> QueueMap = new HashMap<Integer, Runnable>();
    public static void main(String[] args) {
    	//开启10个线程运行
        for (int i = 0; i < 10; i++) {
            JmsThread jmsThread = new JmsThread();
            Thread thread = new Thread(jmsThread);
            thread.setName("线程名称:"+i);
            QueueMap.put(i,jmsThread);
            thread.start();
        }

		//让所有线程运行5s。
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
		//将每个线程中的标志都设置为false
        for (int i = 0; i < 9; i++) {
            JmsThread jmsThread = (JmsThread) QueueMap.get(i);
            jmsThread.keepRunning = false;
        }
        System.out.println("线程0-8已经暂停");

        try {
        	//运行10s
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
		//再将标志为置为true
        for (int i = 0; i < 9; i++) {
            JmsThread jmsThread = (JmsThread) QueueMap.get(i);
            jmsThread.keepRunning = true;
        }

        System.out.println("线程0-8已经启动");
    }
}

输出结果,开始的5s所有线程随机运行,等把前9个线程标志位更改为false后则只有一个线程9在运行,线程内有1s的等待,这里会输出10次,然后将标志位更改为true,又会将所有线程启动运行。

当前运行线程为:线程名称:1
当前运行线程为:线程名称:2
当前运行线程为:线程名称:3
当前运行线程为:线程名称:4
当前运行线程为:线程名称:5
当前运行线程为:线程名称:8
当前运行线程为:线程名称:7
当前运行线程为:线程名称:6
当前运行线程为:线程名称:9
当前运行线程为:线程名称:2
当前运行线程为:线程名称:1
当前运行线程为:线程名称:0
当前运行线程为:线程名称:3
当前运行线程为:线程名称:5
当前运行线程为:线程名称:4
当前运行线程为:线程名称:9
当前运行线程为:线程名称:6
当前运行线程为:线程名称:7
当前运行线程为:线程名称:8
线程0-8已经暂停
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
当前运行线程为:线程名称:9
线程0-8已经启动
当前运行线程为:线程名称:0
当前运行线程为:线程名称:3
当前运行线程为:线程名称:1
当前运行线程为:线程名称:2
当前运行线程为:线程名称:9
当前运行线程为:线程名称:6
当前运行线程为:线程名称:8
当前运行线程为:线程名称:4
当前运行线程为:线程名称:5
当前运行线程为:线程名称:7
当前运行线程为:线程名称:1
当前运行线程为:线程名称:0
当前运行线程为:线程名称:3
当前运行线程为:线程名称:2
当前运行线程为:线程名称:9
当前运行线程为:线程名称:6
当前运行线程为:线程名称:7
当前运行线程为:线程名称:5
当前运行线程为:线程名称:8
当前运行线程为:线程名称:4
当前运行线程为:线程名称:1
当前运行线程为:线程名称:3
当前运行线程为:线程名称:0
当前运行线程为:线程名称:2
当前运行线程为:线程名称:9

使用interrupt()进行中断

/**
 * @author : Erick
 * @version : 1.0
 * @Description :
 * @time :2019-6-13
 */
public class InterruptTest {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <100 ; i++) {
                    System.out.println(Thread.currentThread().getName());
                }
            }
        });
        thread.setName("aaaaa");
        thread.start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
        System.out.println("线程已经暂停");
    }
}

而结果呢,线程不会因为中断请求而中断线程本身的操作,还是会继续执行。

aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
线程已经暂停
aaaaa
aaaaa
aaaaa
aaaaa

通过interrupt方式只是通知要中断线程,具体什么时间中断是靠机器本身来决定的。


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨香异境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值