Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步块是否阻止其他线程访问对象?_Java_Multithreading_Synchronization - Fatal编程技术网

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

Java 同步块是否阻止其他线程访问对象?,java,multithreading,synchronization,Java,Multithreading,Synchronization,如果我对一个同步块内的列表做了一些操作,是否会阻止其他线程在其他地方访问该列表 List<String> myList = new ArrayList<String>(); synchronized { mylist.add("Hello"); } List myList=new ArrayList(); 同步的{ mylist.add(“你好”); } 这是否会阻止其他线程在myList上迭代并删除/添加值 我希望从列表中添加/删除值,但同时防止其他线程/方法

如果我对一个同步块内的列表做了一些操作,是否会阻止其他线程在其他地方访问该列表

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

synchronized {
  mylist.add("Hello");
}
List myList=new ArrayList();
同步的{
mylist.add(“你好”);
}
这是否会阻止其他线程在myList上迭代并删除/添加值


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

在这里,同步化确保一次只有一个线程向myList添加Hello

更具体地说,关于同步wrt对象,您可以使用

synchronized( myList ) //object name
{
    //other code
}
维诺德不,它没有

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

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

synchronized(myList) {
  mylist.add("Hello");
}
Java教程对整个领域进行了很好的解释:


根据我对Java并发控制的有限理解,我想说,上面的代码不太可能呈现您想要的行为

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

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

List myList=new ArrayList()

已同步(myList){ mylist.add(“你好”); }

将给出您描述的行为,方法是在列表本身的lock对象上进行同步

但是,Java文档建议采用这种方式来获取同步列表:

List List=Collections.synchronizedList(新的ArrayList(…);


请参阅:

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


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

在您的示例中,同步块不会编译,您要同步什么?当然,基于此,同步块是您向列表中添加内容的唯一位置。如果其他方法中的其他线程未在同一对象上同步,则它们仍然可以添加和编辑myList。是的,Patrick,为了处理其他线程,我们可能会选择集合。synchronizedList…可能在“此问答区域”之外,但是如果你想对同步进行更多的控制,你也可以使用。哦,没关系。我看到您链接到的教程也提出了锁的概念。更清楚的是,可以说“防止其他线程进入同一实例上同步的任何块”。
List myList = new ArrayList();

synchronized(myList) { mylist.add("Hello"); }
List list = Collections.synchronizedList(new ArrayList(...));