bob*_*bob 35 java concurrency synchronization arraylist
我不确定这是否是同步我的正确方法ArrayList
.
我有一个ArrayList
in_queue
从registerInQueue
函数传入的.
ArrayList<Record> in_queue = null;
public void registerInQueue(ArrayList in_queue)
{
this.in_queue = in_queue;
}
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试同步它.这是否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);
}
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*rdt 46
你正在进行两次同步,这是毫无意义的,可能会减慢代码的速度:在列表上进行迭代时需要对整个操作进行同步,而在这种情况下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,
Run Code Online (Sandbox Code Playgroud)
但在许多情况下,单方法同步是不够的(例如,对于所有迭代,或者当您获得值时,基于它进行计算,并将其替换为结果).在这种情况下,您无论如何都必须使用手动同步,因此Collections.synchronizedList()
只是无用的额外开销.
这是正确的,并记录在案:
http://java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
但是,要清除列表,只需调用List.clear().
是的,这是正确的方法,但如果您希望所有删除一起是安全的,则需要同步块 - 除非队列为空,不允许删除.我的猜测是你只想要安全的队列和出列操作,所以你可以删除synchronized块.
但是,Java中有很多高级并发队列,例如ConcurrentLinkedQueue