You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Things GPIO中断直至wait()超时才触发问题求助

GPIO中断需等待wait()超时才触发的解决方案

看起来你遇到的是经典的线程等待/通知机制的时序问题,结合你的代码,我来分析问题根源并给出具体修复方案:

问题根源分析

你的代码逻辑框架没问题,但有两个关键隐患会导致你看到的现象:

  1. 中断触发早于wait()调用:如果GPIO中断在waitForInterrupt()调用之前就发生了,notifyAll()会被执行,但此时还没有线程在等待notifier对象,后续的wait(5000)会一直等到超时才结束。
  2. 锁竞争导致回调阻塞:如果有其他线程长期持有notifier的锁,GPIO回调线程会被卡在synchronized(notifier)块外,直到wait()超时释放锁后,回调才能执行,看起来就像中断延迟触发了。

修复方案

方案1:添加中断触发标志位(解决时序问题)

通过一个volatile修饰的标志位记录中断是否已发生,避免错过提前触发的中断:

public class Foo {
    private static final Object notifier = new Object();
    // volatile保证多线程间的可见性,确保回调线程修改后,等待线程能立刻看到
    private static volatile boolean interruptTriggered = false;

    public static GpioCallback interrupt = pin -> {
        synchronized (notifier) {
            interruptTriggered = true;
            notifier.notifyAll();
            Log.d("FOO", "Interrupt triggered, notified waiting threads");
        }
        return true;
    };

    public void waitForInterrupt() {
        try {
            synchronized (notifier) {
                // 先检查是否已经触发过中断,避免等待超时
                if (!interruptTriggered) {
                    Log.d("FOO", "Waiting for interrupt...");
                    notifier.wait(5000);
                }
                // 重置标志位,方便下次调用
                interruptTriggered = false;
            }
            Log.d("FOO", "Done.");
        } catch (InterruptedException e) {
            // 不要吞掉中断状态,恢复线程的中断标记
            Thread.currentThread().interrupt();
            Log.e("FOO", "Wait operation was interrupted", e);
        }
    }
}

方案2:排查锁竞争问题(解决回调阻塞)

如果添加标志位后问题依然存在,需要检查是否有其他线程占用notifier锁。可以在synchronized块内添加日志,追踪锁的获取顺序:

  • 在回调的synchronized块内添加日志,确认回调线程何时获取到锁
  • 在waitForInterrupt的synchronized块内添加日志,确认等待线程何时获取到锁

通过日志就能清楚看到是否有锁阻塞的情况,进而定位占用锁的线程。

额外注意事项

  • 确认GPIO回调已正确注册到目标引脚,并且边沿触发模式(上升沿/下降沿/双边沿)配置符合你的需求
  • 不要在synchronized块内执行耗时操作,避免阻塞其他需要获取锁的线程

内容的提问来源于stack exchange,提问作者David Schneider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:09:06