简体   繁体   English

两个线程的同步 ArrayList - 写入和读取

[英]Synchronized ArrayList for two threads - write and read

I need to solve this problem.我需要解决这个问题。 I have console app in which I am inserting some String values.我有控制台应用程序,我在其中插入一些字符串值。 The console app is still running, user can add more and more entries and every 1 minute, there should be another Thread which will print some List statistic (eg size etc.).控制台应用程序仍在运行,用户可以添加越来越多的条目,每 1 分钟,应该有另一个线程将打印一些列表统计信息(例如大小等)。 When I use Main Thread for user's console and different Thread for counting and printing this statistic data to the console (both working with the same List).当我将主线程用于用户的控制台并使用不同的线程来计算此统计数据并将其打印到控制台时(两者都使用相同的列表)。 It is enough to use:使用就足够了:

List<String> list = Collections.synchronizedList(new ArrayList<>());

Or I need to user volatile and access the List in the synchronized block as well?或者我还需要用户 volatile 并访问同步块中的列表?

Thank you!谢谢!

It depends what you want to do with the list.这取决于您要对列表执行的操作。

Collections.synchronizedList(...) simply wraps every method with a synchronized block, synchronizing on itself. Collections.synchronizedList(...)简单地用同步块包装每个方法,在自身上同步。 The synchronization starts when the invoked method starts executing, and stops when it stops executing.同步在被调用的方法开始执行时开始,在它停止执行时停止。

Notionally, it the list is wrapped like this:从概念上讲,它的列表是这样包装的:

class SynchronizedList<T> implements List<T> {
  private List<T> delegate;

  @Override public int size() {
    synchronized (this) {
      return delegate.size();
    }
  }

  // ...
}

As such, doing simple things like list.size() , list.add(...) , list.get(...) don't require any further synchronization.因此,像list.size()list.add(...)list.get(...)这样的简单操作不需要任何进一步的同步。

However, if you want to do more complex things, for example iterating the list, yes, you need additional synchronization:但是,如果您想做更复杂的事情,例如迭代列表,是的,您需要额外的同步:

synchronized (list) {
  for (String s : list) { ... }
}

This is because the synchronization stops as soon as the hidden call to list.iterator() completes;这是因为一旦对list.iterator()的隐藏调用完成,同步就会停止; hence, other threads would be able to modify the list while you are iterating.因此,其他线程将能够在您迭代时修改列表。

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

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