Java 使用锁实现线程暂停

本文介绍了一种在不支持双工的硬件设备上实现同时收发数据的方法,通过使用ReentrantLock和Condition来控制心跳线程的暂停与启动,确保了数据的正确接收和心跳包的稳定发送。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

由于项目需要控制的硬件设备不支持双工,但是却需要做到人眼看不出的同时收发(收:接收其他设备的信息包,可能是UDP包;发:以一定间隔发送心跳包)

解决思路

在收的时候,暂停心跳线程,保证设备接受到的数据正常。

代码

为方便展示,将实现方法放入简易Demo中。主要实现思路:使用ReentrantLock 和 Condition 配合,通过引入一个false标志。实现输入go的时候,开始心跳线程;输入end的时候,暂停心跳线程。

 1public class Demo{
 2        // 使用ReentrantLock 和 Condition 配合
 3    public static ReentrantLock lock = new ReentrantLock();
 4    public static Condition condition = lock.newCondition();
 5
 6        // 是否让心跳线程 暂停的标志
 7    private static boolean pauseFlag = false;
 8
 9        // 程序主入口
10    public static void main(String[] args) {
11        new CommandThread().start();
12        new HeartBeatThread().start();
13
14    }
15
16        // 使用静态内部类的方式,方便演示
17        // 心跳线程
18    public static class HeartBeatThread extends Thread{
19        int count = 0;
20        public void run() {
21            while(true) {
22                lock.lock();
23                try {
24                    if(pauseFlag)
25                        condition.await();
26                 // 模拟心跳包,每次打印
27                    System.out.println(count++);
28                    TimeUnit.SECONDS.sleep(1);
29                } catch (InterruptedException e) {
30                    e.printStackTrace();
31                } finally {
32                    lock.unlock();
33                }
34            }
35        }
36    }
37
38        // 控制暂停线程,如果输入go为开始,end为暂停
39    public static class CommandThread extends Thread{
40        public void run() {
41            Scanner sc = new Scanner(System.in);
42            while(sc.hasNext()) {
43                String command = sc.nextLine();
44
45                if(command.equals("end")) {
46                    pauseFlag = true;
47                    System.out.println("end");
48                }else if(command.equals("go")) {
49                    lock.lock();
50                    System.out.println("go");
51                    pauseFlag = false;
52                    condition.signal();
53                    lock.unlock();
54                }
55            }
56            sc.close();
57        }
58    }
59
60}

 

遇到的坑

尝试使用线程停止,然后再开启线程的方式

具体做法:具体做法使用Thread.interrupt() + break 的 通过捕获异常的方式去停止线程(单独Thread.interrupt()方法不一定会停止线程)

缺点:能够正常停止心跳线程,但是停止线程之后需要重新开启线程(线程停止之后是不能重新start的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值