【问题标题】:Does synchronized block prevent other threads from making insertions into a synchronized list?同步块是否会阻止其他线程插入同步列表?
【发布时间】:2021-12-05 15:56:38
【问题描述】:

所以我正在开发一个多线程 java 应用程序,我有一个问题:

List<Integer> mlist = Collections.synchronizedList(new ArrayList<Integer>());
public void addStuff(int a){
   mlist.add(a) // mlist is a synchronized list
}

public void traverseArray(){
   synchronized(mlist){
    // traversing mlist using normal for loop
   }

}

在上面的代码中,如果一个线程试图使用addStuff() 向mlist 添加一个元素,是否允许另一个线程进入TraverseArray() 方法中的同步块? 或相反亦然 如果一个线程使用TraverseArray()方法中的同步块遍历列表,是否允许另一个线程使用addStuff()方法将元素添加到列表中?

【问题讨论】:

  • 没有。 mlist 在其自身内部同步,因此mlist.add 有效地被synchronized (mlist) { ... } 包围。
  • 你说的同步列表是什么意思?
  • ...换句话说,请扩展您的代码示例以显示列表是如何创建的。下面的答案和 Andy Turner 的评论似乎都假设是您通过调用 Collections.synchronizedList(...) 创建的,但这是真的吗?当您说“同步列表”时,我们怎么知道您说的不是其他内容?
  • @SolomonSlow 是的,我的意思是创建如下列表List&lt;Integer&gt; mlist = Collections.synchronizedList(new ArrayList&lt;Integer&gt;());

标签: java multithreading synchronized


【解决方案1】:

documentation要求在列表上同步。

用户必须手动同步返回的 迭代时列出:

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

因此,只要上述代码在同步块中,您就可以推断其他线程的修改被阻止。

【讨论】:

  • 是的,我知道。我不知道.add() 默认情况下也在同步块内。你是说.add() 不在同步块内?
  • 我是说实现需要显式同步迭代器,不需要显式同步添加。文档保证这是安全的。 (实际上,我们可以猜测“添加”的实现会自行同步,但阅读文档后,我们不需要知道安全使用它)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 2017-05-10
相关资源
最近更新 更多