【问题标题】:Synchronized ArrayList as static method parameter将 ArrayList 同步为静态方法参数
【发布时间】:2018-05-18 03:57:43
【问题描述】:

我有这样的方法:

public static void normalizeMessages(ArrayList<Message> messages){
    synchronized (messages) {
        Collections.sort(messages, new Comparator<Message>() {

            @Override
            public int compare(Message lhs, Message rhs) {
                return lhs.getId().compareTo(rhs.getId());
            }
        });
    }
    // do something with sorted list
} 

我的ArrayList 可以在其他线程的某处修改(添加、删除项目),所以我必须使用synchronized
但我不确定这种方式是否正确,因为我收到了来自Android studio 的警告:同步方法参数'messages'
我是否需要为此 ArrayList 使用 Collections.synchronizedList 并在修改此列表的任何代码中使用 synchronized

【问题讨论】:

  • synchronized 应该在一个通用的“监视器”对象上完成。每个线程都有自己的方法参数副本(即“消息”)。因此,监视器对象在线程之间是不通用的。这实际上会失去同步的好处。
  • @SiddharthaGhosh 所以我必须同步这个方法的调用者?
  • 这不是真的。如果您的所有线程都在使用 same 列表,那么您肯定可以使用该列表进行同步。
  • @GhostCat 好的,你对这个案例有什么建议吗?
  • 并非如此。我想我会研究 Android 研究,看看它是否能解释为什么他们认为这值得警告。

标签: java android synchronized


【解决方案1】:

您可以在类中将此message 参数声明为全局变量并将其设为volatile。因此所有线程都将拥有您的对象的相同副本。因此它将带来synchronization 的好处。

【讨论】:

  • 抱歉,这没有帮助。对数据结构进行同步的目的是防止多个线程同时对其进行更新。这样的竞争可能导致各种数据损坏和不一致。使一个对象 volatile 对这部分没有任何帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多