【问题标题】:java - general synchronizedList questionjava - 一般同步列表问题
【发布时间】:2011-05-24 07:19:02
【问题描述】:

我有一个关于同步列表的一般性问题。
可以说在构造函数中我正在创建一个列表

List synchronizedList = Collections.synchronizedList(list);

我有一种方法将对象添加到列表中。

public void add(String s){ 
    synchronizedList.add(s)
}

还有另一个线程每隔几秒检查一次是否有几行,将其转储到一个文件中并将它们全部删除。

现在假设我迭代每一行并将其保存到数据库中。 在所有迭代之后,我清除了列表。

多线程支持对我有什么帮助?
我可以在另一个线程中的 clear() 发生之前将一个元素添加到列表中。
除非我自己管理锁(我真的不需要同步列表)。

【问题讨论】:

  • 正如所有三个答案所述,同步列表意味着该列表上的所有操作都保证是原子的或保证对单个方法调用的串行访问。我不得不问我的同事这是什么意思。所以这意味着 List 上的操作(来自上面的代码 sn-p)synchronizedList.size()synchronizedList.add(s) 不能并行。这对于一些正在阅读此线程的人来说并不明显。因此,尽管添加以帮助其他不理解的人。感谢@WhiteFang34、@jb-nizet 和 @khachik 的解释。

标签: java synchronized


【解决方案1】:

Collections 返回的同步列表对您的情况没有帮助。仅当您需要保证对单个方法调用的串行访问时,这才很好。如果您需要围绕更大的操作集进行同步,则需要手动将该代码包装在 synchronized 块中。 Javadoc 声明:

用户在迭代返回的列表时必须手动同步它。

如果您的列表在其他地方使用,您至少可以保护它不受单独的方法调用的影响,否则这些方法调用将不是线程安全的。但是,如果您完全管理列表,则只需将 synchronized 块添加到您的 add 方法并使用您在迭代它时将使用的相同锁。

【讨论】:

    【解决方案2】:

    synchronizedList 确实只保证列表上的每个方法调用都是同步的。如果您需要以同步方式完成多个操作,则必须自己处理同步。

    顺便说一句,这在javadoc for Collections.synchronizedList 中明确表示:

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

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

    【讨论】:

      【解决方案3】:

      同步列表意味着该列表上的所有操作都保证是原子的。您描述的场景需要在列表之外进行一些锁定。考虑使用信号量或制作synchronized 块来实现监视器。看看java.util.concurrent

      【讨论】:

        猜你喜欢
        • 2017-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-06
        • 2011-09-21
        相关资源
        最近更新 更多