簡體   English   中英

在java中同步ArrayList的正確方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM