Java:同步列表

Java:同步列表,java,multithreading,list,synchronization,Java,Multithreading,List,Synchronization,我有一个ArrayList,并且我只在一个同步块中操作它,我是否也应该使用Collections.synchronizedList? 例如: 只需使用同步声明,无需显式同步块: List list = Collections.synchronizedList(new ArrayList()); 更改列表内容的唯一方法是调用add或remove,由于这个声明,现在这些方法的同步版本修饰了add或remove 使用显式synchronized块并使用Collections.synchronized

我有一个ArrayList,并且我只在一个同步块中操作它,我是否也应该使用Collections.synchronizedList? 例如:


只需使用同步声明,无需显式同步块:

List list = Collections.synchronizedList(new ArrayList());

更改列表内容的唯一方法是调用add或remove,由于这个声明,现在这些方法的同步版本修饰了add或remove

使用显式
synchronized
块并使用
Collections.synchronizedList(new ArrayList())
将在互斥方面等效工作。但是,如果您必须迭代调用
集合返回的列表,则必须按照java规范在该列表上显式地进行外部同步(抱歉,我不想在这里链接到它)

另一件需要考虑的事情是开销。代码>集合。synchronizedList(List orig)
创建一个新对象,用于控制对原始列表实现的访问。根据您计划进行此调用的频率,以及访问原始列表对象的不同方式,您最好从外部对其进行同步。

  • 如果只在
    synchronized
    块中访问列表,则不需要
    synchronizedList()

  • 如果您仅使用基本操作(
    add()
    remove()
    ,等等)访问列表,并且这些操作的调用互不依赖(即原子性不是问题),那么您只能使用
    synchronizedList()
    ,而不使用显式
    synchronized

  • 如果您希望能够在不使用
    synchronized
    块的情况下调用基本操作,但同时也要使用原子化的复合操作(包括迭代),那么对于复合操作,您需要使用
    synchronizedList()
    synchornized


只有一个就足够了。仅使用
synchronizedList
我认为块对于迭代、排序等是必要的。我的疑问实际上只是声明,如果我将所有代码包装起来,我需要将列表声明为已同步。非基本操作只是迭代?我总是只看到这些示例,而没有看到其他示例,所以“只是迭代的块”?如果(!list.contains(…))list.add(…)@Tatanan,“not elementary”意味着任何操作序列会暂时使数据处于不一致/无效/非法状态,那么也可能存在原子化的复合操作。经典的例子是一个程序,它从一个银行账户中取出资金并存入另一个账户。在取款和存款之间有一个瞬间,当账簿不正确时。如果审计员线程在这一瞬间碰巧查看了这两个帐户,它将报告一个违规行为。将这两个操作放在一个同步块中会使它们成为一个原子单元,并且会阻止审计员看到处于该状态的帐户。
List list = Collections.synchronizedList(new ArrayList());