java - 处理共享资源上的信号量冲突的最佳实践是什么?

标签 java android concurrency semaphore

我有一些代码存储特定 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/

相关文章:

android - 尝试建立APK时发生错误

java - 当文档不在工作集中时,使用 upsert 和唯一索引原子性进行 MongoDB 更新

java - 文件存在,但在 toast 中它是空的

java - 输入字符串之间的模式

android - 在 onChildClickListener 中使用 Intent 找不到方法

android - 如何让 Android Studio 1.1 在 "Make"指令期间调用 generateDebugTestSources 而不是 assembleDebugTest?

Java 监视器代替二进制信号量

mysql - Postgres 的并发参数

java - 在 Android 上访问 chromium 类

java - 如何将依赖于部署的参数传递给 webapp