我有两个线程都需要访问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();
            }
        }
    }
});

最佳答案

最简单的方法是将列表类型更改为thread safe list implementation:

private List<short[]> list = new CopyOnWriteArrayList<short[]>();

请注意,如果您对列表进行大量更改(添加/删除),则这种列表的效率不是很高-但是,如果它对您有用,那是一个简单的解决方案。

如果需要更高的效率,可以改用synchronized list:
private List<short[]> list = Collections.synchronizedList(new ArrayList<short[]>());

但是您将需要进行同步以进行迭代:
synchronized(list) {
    for(short[] item : list) {
        //process the data
    }
}

编辑:使用BlockingQueue的建议可能更好,但需要在代码中进行更多更改。

关于java - 访问java ArrayList时如何停止两个线程冲突?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16652629/

10-09 02:48