[英]Correct way to synchronize ArrayList in java
我不确定这是否是同步我的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)
,你正在使用synchronized (in_queue_list)
进行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 (或它的兄弟姐妹)可能有用。 他们会为您管理同步,因此线程可以写入队列或查看/获取,而无需您进行额外的同步工作。
这是正确的,并记录在案:
http://java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
但是,要清除列表,只需调用List.clear() 。
是的,这是正确的方法,但如果您希望所有删除一起是安全的,则需要同步块 - 除非队列为空,不允许删除。 我的猜测是你只想要安全的队列和出列操作,所以你可以删除synchronized块。
但是,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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.