2017-06-16 27 views
1

我有一些代码存储发生于特定视图MotionEvents(这个制片人),并在另一个线程读取用于显示的数据(称之为消费者)的一些不同的代码。我本质上是重新创建一个不同颜色的按钮功能,而使用标准的Android按钮是不可行的。 MotionEvents存储在一个ArrayList中。对此的访问被封装在单个许可信号中,以防止提供者和消费者同时对I/O访问ArrayList并读取暂时数据。一切都很好。通过共享资源处理信号量冲突的最佳做法是什么?

的问题是,当我敲击这个以高速查看。在生产者方面,我向ArrayList添加东西以响应MotionEvent.ACTION_DOWN,并将其从列表中移除以响应MotionEvent.ACTION_UP(我忽略了ACTION_MOVEs)。如果用水龙头淹没手机,当需要添加/删除时,信号量不可用,无论是因为我的消费者正在读取ArrayList,还是因为我没有完成处理上一个水龙头。

那么,什么是这个问题的最佳做法?如果我错过MOTION_DOWN,好像我可以放心地忽略它,但是如果我错过了MOTION_UP,我的消费者是不是会卡住显示按钮,就像手指仍被按下一样?我看到偶尔的显示错误(与快速轻敲无关),可能是由于错过了MOTION_UP而导致的。

+0

'信号量可以关闭'是什么意思? – EJP

+0

愚蠢的错字,对不起。我的意思是,信号不可用 – user1733212

+0

所以,我不完全理解你的问题,有些代码会好很多帮助,但让我们来试试。 Android完全支持Java 7吗?那么,为什么你不依赖于Java高水平并发对象来控制这个https://docs.oracle.com/javase/tutorial/essential/concurrency/highlevel.html,它将可能,更可靠。 另一种选择它可能使你的数组​​列表线程安全的:'Collections.synchronizedList(新的ArrayList <>())' –

回答

0

这是很难说,现在正是错你的计划,但你可能有一些同步问题。

对于生产者 - 消费者拍打,BlockingQueue是你最好的选择。就你而言,只需使用简单的无限制实​​现。

响应按钮点击执行mBlockingQueue.add(MotionEvent),并在后台线程无限循环消耗事件:

while(true) { 
    processEvent(mBlockingQueue.take()); 
} 

作为一个方面说明:我不认为你真的需要后台线程,以便单击时更改按钮的颜色。有other simpler ways

+0

@Vasilly我做的BlockingQueue一些研究你的建议后。我使用CopyOnWriteArrayList结束了,所以感谢我指出了这个大方向。 – user1733212

相关问题