在java中同步ArrayList的正确方法

我不确定这是否是同步我的.ArrayList

我有一个从函数传入的。ArrayListin_queueregisterInQueue

ArrayList<Record> in_queue = null;

public void registerInQueue(ArrayList in_queue)
{
    this.in_queue = in_queue;
}

现在我正在尝试同步它。这是否正确地同步了我的对象?in_queue

List<Record> in_queue_list = Collections.synchronizedList(in_queue);

synchronized (in_queue_list) {
    while (in_queue_list.size() > 0) {
        in_queue_list.remove(0);
    }
}

答案 1

您正在同步两次,这是毫无意义的,并且可能会减慢代码速度:迭代列表时的更改需要对整个操作进行同步,在这种情况下,您使用Use执行的操作是多余的(它会创建一个同步单个操作的包装器)。synchronized (in_queue_list)Collections.synchronizedList()

但是,由于您正在完全清空列表,因此迭代删除第一个元素是最糟糕的方法,对于每个元素,必须复制所有后续元素,使此操作成为O(n^2)操作 - 对于较大的列表来说非常慢。

相反,只需调用 - 无需迭代。clear()

编辑:如果您需要稍后的单方法同步,那么这是正确的方法:Collections.synchronizedList()

List<Record> in_queue_list = Collections.synchronizedList(in_queue);
in_queue_list.clear(); // synchronized implicitly, 

但在许多情况下,单方法同步是不够的(例如,对于所有迭代,或者当您获得值时,基于它进行计算,并将其替换为结果)。在这种情况下,无论如何都必须使用手动同步,因此只是无用的额外开销。Collections.synchronizedList()


答案 2

看看你的例子,我认为ArrayBlockingQueue(或其兄弟姐妹)可能会有用。它们为您处理同步,因此线程可以写入队列或查看/获取,而无需您进行额外的同步工作。


推荐