我有一些代码存储特定 View 发生的 MotionEvent(称为生产者),以及另一个线程中的一些不同代码,用于读取该数据以用于显示目的(称为消费者)。我本质上是在重新创建“向下一种颜色向上一种不同颜色”的按钮功能,而使用标准 Android 按钮是不可行的。 MotionEvent 存储在单个 ArrayList 中。对此的访问被包装在单个许可信号量中,以防止提供者和消费者同时 I/O 到 ArrayList 并读取临时数据。一切都很好。
问题是当我高速点击此 View 时。在生产者方面,我将内容添加到 ArrayList 中以响应 MotionEvent.ACTION_DOWN,并从列表中将其删除以响应 MotionEvent.ACTION_UP(ACTION_MOVEs 我忽略)。如果我用水龙头淹没手机,当需要添加/删除时,信号量不可用,要么是因为我的消费者正在读取 ArrayList,要么因为我还没有处理完之前的水龙头。
那么解决这个问题的最佳实践是什么?如果我错过了 MOTION_DOWN,似乎我可以安全地忽略它,但如果我错过了 MOTION_UP,我的消费者是否会被卡住显示按钮,就像手指仍然按下一样?我偶尔会看到一个显示错误(与快速点击无关),这可能是由于错过 MOTION_UP 造成的。
最佳答案
现在很难判断您的方案到底出了什么问题,但您可能确实遇到了一些同步问题。
对于生产者-消费者模式,BlockingQueue
是您的最佳选择。在您的情况下,只需使用简单的无限制实现。
执行mBlockingQueue.add(MotionEvent)
来响应按钮点击,并在后台线程上无限循环地消费事件:
while(true) {
processEvent(mBlockingQueue.take());
}
作为旁注:我认为您并不真正需要后台线程来更改单击时按钮的颜色。有other simpler ways .
关于java - 处理共享资源上的信号量冲突的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44581273/