Android中活跃线程中断问题:双线程互斥中断实现疑问
如何正确实现可互相中断且互斥运行的线程
首先得纠正一个常见误区:Thread.interrupt()不会主动触发异常——它只是给目标线程设置一个「中断标记位」,只有当目标线程正处于sleep()、wait()、join()这类阻塞方法时,才会抛出InterruptedException,同时清除这个标记位。如果线程在正常执行代码逻辑,完全不会自动抛出异常,得靠你自己主动检查中断状态来终止线程。
结合你的需求(两个线程互斥运行、可互相中断),我给你一套可行的实现方案:
核心思路
- 互斥运行:用同步锁(比如
synchronized或者ReentrantLock)保证同一时间只有一个线程能执行核心逻辑 - 响应中断:每个线程在运行过程中定期检查自己的中断标记,一旦检测到被中断就立刻退出
- 互相中断:让两个线程互相持有对方的引用,在需要时调用对方的
interrupt()方法触发中断
代码示例
下面是一个用synchronized实现的完整例子,两个线程交替尝试获取锁,并且可以互相中断:
public class MutualInterruptThreads { // 共享锁对象,保证互斥 private static final Object lock = new Object(); // 两个线程的引用,用于互相中断 private Thread threadA; private Thread threadB; public void startThreads() { // 线程A的逻辑 threadA = new Thread(() -> { try { while (!Thread.currentThread().isInterrupted()) { synchronized (lock) { System.out.println("线程A正在运行..."); // 模拟核心业务逻辑,替换成你的实际代码即可 Thread.sleep(1000); // 尝试中断线程B if (threadB != null && threadB.isAlive()) { System.out.println("线程A尝试中断线程B"); threadB.interrupt(); } } // 让出CPU,给线程B获取锁的机会 Thread.yield(); } } catch (InterruptedException e) { // 捕获到中断异常,说明线程A在阻塞时被中断 System.out.println("线程A被中断,退出运行"); // 注意:捕获异常后中断标记会被清除,这里重新设置标记,保证上层逻辑能感知 Thread.currentThread().interrupt(); } }, "Thread-A"); // 线程B的逻辑(和A逻辑对称) threadB = new Thread(() -> { try { while (!Thread.currentThread().isInterrupted()) { synchronized (lock) { System.out.println("线程B正在运行..."); Thread.sleep(1000); // 尝试中断线程A if (threadA != null && threadA.isAlive()) { System.out.println("线程B尝试中断线程A"); threadA.interrupt(); } } Thread.yield(); } } catch (InterruptedException e) { System.out.println("线程B被中断,退出运行"); Thread.currentThread().interrupt(); } }, "Thread-B"); threadA.start(); threadB.start(); } public static void main(String[] args) throws InterruptedException { MutualInterruptThreads demo = new MutualInterruptThreads(); demo.startThreads(); // 让程序运行5秒后主动结束 Thread.sleep(5000); demo.threadA.interrupt(); demo.threadB.interrupt(); } }
关键细节说明
- 检查中断标记:在循环条件中用
!Thread.currentThread().isInterrupted(),每次循环都会检查是否被中断,一旦标记为true就退出循环 - 处理InterruptedException:当线程在
sleep()时被中断会抛出该异常,此时中断标记会被清除,所以在catch块中重新调用Thread.currentThread().interrupt(),确保上层逻辑能感知到中断信号 - 互斥锁的使用:
synchronized(lock)保证同一时间只有一个线程能进入同步块执行核心逻辑,满足你“二者不能同时运行”的要求 - 禁用stop():
Thread.stop()已经被废弃,它会强制终止线程,可能导致资源泄漏、数据不一致等严重问题,绝对不要使用
额外提醒
如果你的线程涉及IO操作(比如网络读写、文件操作),部分IO是不可中断的,这时候需要额外处理:比如主动关闭IO流,让线程从阻塞的IO操作中返回,再检查中断标记退出。
内容的提问来源于stack exchange,提问作者BlueSeph
相关产品推荐
相关产品推荐

