【问题标题】:Does a synchronized block prevent other thread access to object?同步块是否会阻止其他线程访问对象?
【发布时间】:2010-11-08 10:15:54
【问题描述】:

如果我对同步块内的列表执行某些操作,是否会阻止其他线程在其他地方访问该列表?

List<String> myList = new ArrayList<String>();

synchronized {
  mylist.add("Hello");
}

这是否会阻止其他线程遍历 myList 并删除/添加值?

我希望从列表中添加/删除值,但同时保护它免受其他线程/方法对其进行迭代(因为列表中的值可能无效)

【问题讨论】:

  • 在您的示例中,同步块将无法编译,您要同步什么?

标签: java multithreading synchronization


【解决方案1】:

不,它没有。

synchronized 块仅阻止其他线程进入该块(更准确地说,它阻止其他线程进入在同一对象实例上同步的所有块 - 在这种情况下是在 this 上同步的块)。

您需要在synchronized 块中使用您要保护的实例:

synchronized(myList) {
  mylist.add("Hello");
}

Java 教程中对整个区域进行了很好的解释:

http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

【讨论】:

  • 可能在“本问答区域”之外,但如果您想对同步进行更多控制,您也可以使用Lock
  • 哦,没关系。我看到您链接到的教程也提出了锁的概念..
  • 说“防止其他线程进入同一实例上同步的any块会更清楚。
【解决方案2】:

是的,但仅当对myList 的所有其他访问都受到同一对象上的同步块的保护时。您发布的代码示例缺少您同步的对象(即您获取互斥锁的对象)。如果您在不同的对象上同步或在一个实例中根本无法同步,那么其他线程很可能同时访问该列表。因此,在访问列表之前,您必须确保所有线程都必须进入同一个对象上的同步块(例如,始终使用synchronized (myList) { ... })。事实上,已经有一个工厂方法可以用同步方法为您包装列表中的每个方法:Collections.synchronizedList

但是,您当然可以使用Collections.synchronizedList 包装您的列表,以便其所有方法单独同步,但这并不一定意味着您的应用程序的不变量得到维护。将列表的每个方法单独标记为已同步将确保列表的内部状态保持一致,但您的应用程序可能希望更多,在这种情况下您将需要编写一些更复杂的同步逻辑或看看您是否可以利用 @ 987654322@(强烈推荐)。

【讨论】:

    【解决方案3】:

    这里同步确保一次只有一个线程将 Hello 添加到 myList...

    更具体地说,同步你可以使用的 wrt 对象

    synchronized( myList ) //object name
    {
        //other code
    }
    

    葡萄酒

    【讨论】:

    • 当然,基于同步块是您向列表中添加内容的唯一位置。其他方法中的其他线程如果没有在同一个对象上同步,仍然可以添加和编辑myList。
    • 是的,Patrick,为了照顾其他线程,我们可能会选择 Collections.synchronizedList...
    【解决方案4】:

    根据我对 Java 并发控制的有限理解,我会说上面的代码不太可能呈现您正在寻找的行为。

    同步块将使用您在其中调用所述代码的任何对象的锁,这绝不会阻止任何其他代码访问该列表,除非所述其他代码也使用相同的锁对象进行同步。

    我不知道这是否可行,或者是否有任何建议,但我认为:

    List myList = new ArrayList();
    
    

    synchronized(myList) { mylist.add("Hello"); }

    将通过在列表本身的锁定对象上同步来给出您描述的行为。

    但是,Java 文档推荐这种方式来获取同步列表:

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

    见:http://download.oracle.com/javase/1.4.2/docs/api/java/util/ArrayList.html

    【讨论】:

      猜你喜欢
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多