Java 包含一些数据的非同步收集对象,需要同步包装器,但不';我不想引用原始对象

Java 包含一些数据的非同步收集对象,需要同步包装器,但不';我不想引用原始对象,java,collections,synchronization,Java,Collections,Synchronization,我目前正在研究上的Java集合,遇到了以下段落 这些方法中的每一个都返回由指定集合备份的同步(线程安全的)集合。为了保证串行访问,必须通过返回的集合完成对备份集合的所有访问。保证这一点的简单方法是不保留对支持集合的引用。使用以下技巧创建同步集合 List<Type> list = Collections.synchronizedList(new ArrayList<Type>()); List List=Collections.synchronizedList(新的Ar

我目前正在研究上的Java集合,遇到了以下段落

这些方法中的每一个都返回由指定集合备份的同步(线程安全的)
集合
。为了保证串行访问,必须通过返回的集合完成对备份集合的所有访问。保证这一点的简单方法是不保留对支持集合的引用。使用以下技巧创建同步集合

List<Type> list = Collections.synchronizedList(new ArrayList<Type>());
List List=Collections.synchronizedList(新的ArrayList());

我只是想知道,如果我有一个尚未同步且包含一些数据的集合实例(备份集合),并且我想将此集合实例(备份集合)转换为同步集合,但不想保留对备份集合的引用,会发生什么情况。这怎么可能呢?可能吗?如果是,这是人们通常会做的吗?

为了保证您不保留对支持集合的引用,请退出引用范围

换句话说,声明对块内后备数组的引用,并确保该引用仅传递给
Collections.synchronizedList()
方法。退出该块时,引用将丢失,并且可以确保只有同步包装器引用备份集合

这不是一种常见的方法,但只要包装后不对备份集合进行更改,就不会导致并发问题。然而,这可能会引起同事们的一些争论,他们知道所引用的习惯用法是安全的,但不确定你的创新。这可能是通过包装器而不是后台集合添加元素的充分理由

下面是一个例子:

class MyObj {

  private final List<Type> list;

  MyObj(/* Some arguments that control initial list contents */) {
    List<Type> tmp = new ArrayList<>();
    tmp.add(...);
    list = Collections.synchronizedList(tmp);
  } /* Reference to `tmp` is lost, safety is ensured. */

}
类MyObj{
私人最终名单;
MyObj(/*一些控制初始列表内容的参数*/){
List tmp=new ArrayList();
tmp.添加(…);
列表=集合.synchronizedList(tmp);
}/*对“tmp”的引用丢失,安全得到保证*/
}

如果您计划更改收藏的状态,为什么不先复制一份呢?当然,您可以包装现有的收藏。最好不要保留对支持集合的引用,因为这样可以确保它不会被意外修改。您的问题不清楚。。你可以得到一个新的列表,并很容易地将旧的列表转储