Java 同步列表是如何工作的?

Java 同步列表是如何工作的?,java,multithreading,synchronization,Java,Multithreading,Synchronization,我不确定我是否理解Java中的同步列表。假设我有以下几点: List<Integer> numbers = Collections.synchronizedList(new ArrayList<Integer>()); // Assumption: This is running on a separate thread public void add() { numbers.add(new Random().nextInt(100)); } /

我不确定我是否理解Java中的同步列表。假设我有以下几点:

 List<Integer> numbers = Collections.synchronizedList(new ArrayList<Integer>());

 // Assumption: This is running on a separate thread
 public void add() {
      numbers.add(new Random().nextInt(100));
 }

 // This is also running on a separate thread
 public void doSomething() {
      synchronized(numbers) {
           for (int i : numbers) {}
      }
 }
List number=Collections.synchronizedList(新的ArrayList());
//假设:这是在一个单独的线程上运行的
公共无效添加(){
add(new Random().nextInt(100));
}
//这也在一个单独的线程上运行
公共无效剂量测定法(){
已同步(数字){
对于(int i:number){}
}
}
基本上,如果调用了
doSomething()
,那么
add()
是否能够向列表中添加数字?如果我改为使用
public synchronized void add()
public synchronized void doSomething()
,会发生什么情况


我正在一个UDP套接字服务器上工作,我打算将客户机存储在
ArrayList
中。我将有多个线程可以读取、写入和修改此列表。我应该做什么?

这应该可以。根据的文档,list mutator方法(
add()
等)在list对象本身上同步。由于迭代循环也在
synchronized
块中,所以一切都应该很好

如果调用doSomething(),add()是否能够向列表中添加数字

不,直到调用doSomething()的线程离开同步块

如果我改为使用public synchronized void add()和public synchronized void doSomething(),会发生什么

假设只有这些地方使用了列表,效果是一样的。但是您可以在包含列表的对象上同步,而不是在列表本身上同步


基本上,对共享状态的所有访问必须在同一个锁上同步。您可以选择您喜欢的锁。您可以使用CopyOnWriteArrayList之类的并发集合,而不是使用同步列表或同步方法。

我很困惑;其他人说了相反的话。@BrandonSmith,这个答案清楚地解释了您的代码行为,因为两个操作在任何一种情况下都是在同一对象上同步的。@@BrandonSmith-忘记我前面的答案。你的代码很好。我不知道“你的代码很好”是什么意思。为了明确说明,如果doSomething()正在处理,add()将无法向列表中添加数字。@Integrator-True,对
add()
的调用将被阻止,直到
doSomething()
退出同步代码。在执行
doSomething()
时调用
add()
是非常安全的。OP正在考虑将方法
同步化
作为替代方案;就阻塞而言,其行为方式完全相同,不会提供额外的保护。因此,当前的代码很好。