正确的方法来同步在java中的ArrayList(Correct way to synchroniz

2019-07-18 04:23发布

我不知道这是否是我的同步正确的方法ArrayList

我有一个ArrayList in_queue其从传递registerInQueue功能。

ArrayList<Record> in_queue = null;

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

现在我正在努力进行同步。 这是我的sychronizing 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);
    }
}

Answer 1:

你是同步的两倍,这是毫无意义的,可能会减慢代码:变化,同时遍历列表需要在整个操作中,您用做synchronnization 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()仅仅是无用的额外开销。



Answer 2:

看着你的榜样,我觉得ArrayBlockingQueue (或同级)可能会使用的。 他们找你的同步之后,所以线程可以写入队列或PEEK /取而不需要您额外的同步工作。



Answer 3:

这是正确的,并记录在案:

http://java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

然而,清除列表,只需调用List.clear() 。



Answer 4:

是的,这是正确的做法,但如果你希望所有的清除在一起是安全的synchronized块是必需的 - 除非队列为空允许没有清除。 我的猜测是,你只是想安全的队列和队列操作,这样可以去掉synchronized块。

不过,也有在Java中远远先进的并发队列如的ConcurrentLinkedQueue



Answer 5:

让我们以一个正常的列表(由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());
            }
        }    
    }
}

请注意,遍历列表时,该访问依然采用了synchronized块的synchronizedList对象锁定完成。 在一般情况下,遍历同步收集应在synchronized块来实现



文章来源: Correct way to synchronize ArrayList in java