Sab*_*bin 1 java concurrency multithreading android synchronization
我有两个线程都需要访问ArrayList<short[]>实例变量.
short[]当新数据到达时,一个线程将通过回调异步地将项添加到列表中:void dataChanged(short[] theData)
另一个线程将定期检查列表是否有项目,如果是,它将迭代所有项目,处理它们,并从阵列中删除它们.
如何设置它以防止两个线程之间的冲突?
这个人为的代码示例当前抛出了java.util.ConcurrentModificationException
//instance vairbales
private ArrayList<short[]> list = new ArrayList<short[]>();
//asynchronous callback happening on the thread that adds the data to the list
void dataChanged(short[] theData) {
list.add(theData);
}
//thread that iterates over the list and processes the current data it contains
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
for(short[] item : list) {
//process the data
}
//clear the list to discared of data which has been processed.
list.clear();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
您可能希望使用生成器使用者队列,例如ArrayBlockingQueue替代或类似的并发集合.
生产者 - 消费者问题(也称为有界缓冲问题)是多进程同步问题的典型示例.该问题描述了两个进程,生产者和使用者,他们共享一个用作队列的通用固定大小缓冲区.制作人的工作是生成一段数据,将其放入缓冲区并重新开始.同时,消费者一次一件地消费数据(即,将其从缓冲器中移除).问题是确保生产者不会尝试将数据添加到缓冲区(如果已满)并且消费者不会尝试从空缓冲区中删除数据.
一个线程offers short[]和另一个线程s take().
最简单的方法是将列表类型更改为线程安全列表实现:
private List<short[]> list = new CopyOnWriteArrayList<short[]>();
Run Code Online (Sandbox Code Playgroud)
请注意,如果您对其进行大量变异(添加/删除),这种类型的列表并不是非常有效 - 但如果它对您有用,那是一个简单的解决方案。
如果您需要更高的效率,可以使用同步列表代替:
private List<short[]> list = Collections.synchronizedList(new ArrayList<short[]>());
Run Code Online (Sandbox Code Playgroud)
但是您需要同步以进行迭代:
synchronized(list) {
for(short[] item : list) {
//process the data
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:使用 a 的建议BlockingQueue可能更好,但需要对代码进行更多更改。
| 归档时间: |
|
| 查看次数: |
1419 次 |
| 最近记录: |