当前位置: 首页 > 面试题库 >

为什么我需要同步Collections.synchronizedList返回的列表

慕容安易
2023-03-14
问题内容

我在dos.oracle.com上找到了这个

公共静态列表syncedList(列表列表)

返回由指定列表支持的同步(线程安全)列表。为了保证串行访问,至关重要的是,对后备列表的所有访问都必须通过返回的列表来完成。当用户遍历返回列表时,必须手动对其进行同步:

  List list = html" target="_blank">Collections.synchronizedList(new ArrayList());
      ...
  synchronized(list) {
      Iterator i = list.iterator(); // Must be in synchronized block
      while (i.hasNext())
          foo(i.next());
  }

我的问题是:如果Collections.synchronizedList();应该返回已经同步的列表,为什么我必须同步列表以对其进行迭代?

我只是在两个线程中访问列表:一个线程只是添加,另一个线程获取和删除。您推荐用于此方案的其他哪些类?

谢谢阅读。


问题答案:

正在同步的列表仅表示addremove等操作已同步,因此是原子的。但是,迭代不是,如果一个线程adds在另一个线程之间进行迭代,则可能会收到ConcurrentModificationException。

通过手动同步迭代块,可以确保在迭代时不修改列表。

一种替代方法是使用提供迭代器的aCopyOnWriteArrayList,该迭代器在迭代开始时
就知道 该列表的迭代,而与后续修改无关。但是,如果您需要经常更改列表的内容,则收集效率不是很高。



 类似资料:
  • 问题内容: 我正在尝试使用两个线程将值添加到中。我想要的是,当一个线程正在添加值时,另一个线程不应干涉,因此我使用了该方法。但是看来,如果我没有在对象上显式同步,则添加操作将以不同步的方式进行。 没有显式的同步块: 我得到的输出是: 在未注释显式同步块的情况下,我在添加时停止了来自其他线程的干扰。一旦线程获得了锁,它将一直执行直到完成。 取消注释同步块后的样本输出: 那么为什么不进行同步呢? 问题

  • 我正在尝试使用两个线程将值添加到。我想要的是,当一个线程添加值时,另一个线程不应该干扰,所以我使用了 方法。但是,如果我不显式同步对象,则添加似乎是以不同步的方式完成的。 没有显式同步块: 我得到的输出是: 通过取消对显式synchronized块的注释,我在添加时停止了来自其他线程的干扰。一旦线程获得了锁,它就一直执行,直到完成。 取消注释同步块后的示例输出: 那么,为什么<code>集合会出现

  • 问题内容: 当您使用Exception类扩展一个类(用于创建新的异常)时,会收到警告,提示您有一个。我知道这在序列化和反序列化过程中起着重要的作用,但是何时需要序列化我的Exception?谁能给我一个实际的案例,让我的自定义异常类具有序列化和反序列化? 问题答案: 这是因为所有异常的根类都实现了接口。默认情况下,所有异常都是可序列化的,这是一种语言设计决策,因为作者希望异常能够在没有任何特殊配置

  • 我为我的密码学初学者水平道歉 在我的项目中,我发现在将密码插入数据库之前需要对密码进行散列,因此我搜索了顶级散列算法,发现了PBKFD2和salt方法。 我这样做的方法是生成随机64char Salt并使用它来散列密码。然后将哈希密码和salt存储在我的数据库中。(注:注册时也会生成密码。这不是我的选择) 登录时,我的Servlet获取密码,然后用数据库中存储的salt散列它。但是我得到了不同的结

  • 问题内容: 考虑一下这个功能: 有人可以解释一下为什么L1和L2显然无法到达时没有给出警告,而L3却给出了警告。 问题答案: 因为就编译器而言,这只是另一个方法调用。 它所做的是结束过程这一事实只能从实现中找到(这是本机代码,而没有任何区别)。 如果你必须把你的代码(通常也最好避免它,除非你想返回0以外的代码),它应该是一个方法,返回,例如。这样更好。 关于可达性,解释是相同的:是Java语言的关

  • 我有一个方法,它检查一个对象是否已经存在于数组列表中,如果存在,则用新对象替换索引,如果不存在,则添加新对象。 当我编写方法时,我没有返回类型。我收到一个错误,建议我将返回类型设置为void,所以我就这样做了。然后我得到了另一个错误,返回类型必须是布尔的。我唯一的问题是方法本身本质上(至少对我来说)不是true/false返回。我需要它做的只是在ArrayList中添加/替换一个对象,而不是返回任