繁体   English   中英

同步块是否阻止其他线程访问对象?

[英]Does a synchronized block prevent other thread access to object?

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

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

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

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

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

不,不是的。

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

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

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

整个区域在Java教程中得到了很好的解释:

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

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

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

这里sychronized确保一次只有一个线程向myList添加Hello ...

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

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

维诺德

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

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

我不知道这是否有用,或者是否以任何方式建议,但我认为:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM