Collections.sort() 同步

问题描述 投票:0回答:1

我有一个列表,我需要在 Java 中以线程安全的方式对其进行排序。我需要返回一个列表。

我写了下面的代码,但由于

myListToOrder
已经是
synchronizedList
我不确定
Collections.sort(myListToOrder);
是否需要位于
synchronized
块内。

private  List<String> sortSynchronized(){
    List<String> myListToOrder = Collections.synchronizedList(this.myList);
            synchronized (myListToOrder) {
                Collections.sort(myListToOrder);
            }
return myListToOrder;
}

注意:

myList
创建为:
protected final List<String> myList = Lists.newArrayList();

对此有什么意见吗?

java multithreading thread-safety
1个回答
1
投票

您需要确保在排序时没有对列表的访问(所有访问都需要“发生在排序之前”或“发生在排序之后”)。

在您的情况下,您有一个

List
,在
synchronized
上创建 List
视图
,并在该视图上创建
synchronize
。但是,其他代码仍然可以同时访问原始列表。

您可以通过对所有操作使用相同的

synchronizedList
来解决此问题:


private final List<String> myList = Collections.synchronizedList(new ArrayList<>());

private List<String> sortSynchronized(){
    synchronized (myList) {//no other access to myList is possible during this block
        Collections.sort(myListToOrder);
    }
    return myListToOrder;
}

或者,您可以为该列表引入您自己的同步策略,并以这种方式保护对

List
的所有访问,例如使用
ReadWriteLock

但是,应该注意的是,在

List
完成后,对
sortSyncronized
的其他访问可能会扰乱排序。您可能想要(排序并)返回一个副本,而不是返回相同的
List

private List<String> sortedCopy(){
    synchronized(myList){//or however you want to secure access - elements being added to the list during copying might cause issues
        List<String> copy = new ArrayList<>(myList);
    }
    Collections.sort(copy);
    return copy;
    //or if you want to have a synchronizedList
    //return Collections.synchronizedList(copy); 
}
© www.soinside.com 2019 - 2024. All rights reserved.