我有一个列表,我需要在 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();
对此有什么意见吗?
您需要确保在排序时没有对列表的访问(所有访问都需要“发生在排序之前”或“发生在排序之后”)。
在您的情况下,您有一个
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);
}