我不确定这是否是同步我的 ArrayList 的正确方法。

我有一个 ArrayList in_queue ,它是从 registerInQueue 函数传入的。

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);
    }
}
有帮助吗?

解决方案

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

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

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

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

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

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

其他提示

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

是的,这是正确的方法,但如果您希望所有删除一起是安全的,则需要同步块 - 除非队列为空,不允许删除。我的猜测是你只需要安全队列和出队操作,这样你就可以删除同步块。

但是,Java中有很多高级并发队列,例如 ConcurrentLinkedQueue

让我们采用一个普通的列表(由ArrayList类实现)并使其同步。这显示在SynchronizedListExample类中。     我们传递Collections.synchronizedList方法一个新的字符串ArrayList。该方法返回一个同步的字符串列表。     //这是SynchronizedArrayList类

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
* @email kumarmanoj.mtech@gmail.com
* 
*/
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
    public static void main(String[] args) {    
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());
        synchronizedList.add("Aditya");
        synchronizedList.add("Siddharth");
        synchronizedList.add("Manoj");
        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<String> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Synchronized Array List Items: " + iterator.next());
            }
        }    
    }
}

请注意,在遍历列表时,仍然使用锁定synchronizedList对象的synchronized块完成此访问。 通常,迭代同步集合应该在同步块中完成

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top