简体   繁体   English

线程安全的 ArrayList 合并:这可行吗?

[英]Thread-Safe ArrayList merge: will this work?

  private static final ExecutorService ES = Executors.newWorkStealingPool();

  public Future<List<String>> isThisSafe() {
    List<String> a = new ArrayList<>();
    a.add("a");
    List<String> b = new ArrayList<>();
    b.add("b");

    return ES.submit(() -> {
      a.addAll(b);
      return a;
    });
  }

I'll say that thread X is the one that calls isThisSafe().我会说线程 X 是调用 isThisSafe() 的线程。 Thread Y runs the Callable submitted to the ExecutorService.线程 Y 运行提交给 ExecutorService 的 Callable。

Right now, I think this works.现在,我认为这行得通。

✓ The two ArrayLists are never modified by X after being published to Y ✓ 这两个 ArrayList 发布到 Y 后,再也不会被 X 修改

✓ ArrayList 'a' is modified by thread Y, but X does not hold a reference to 'a'.. the returned reference to 'a' would be considered 'new' and so X will pull this from MM. ✓ ArrayList 'a' 被线程 Y 修改,但 X 不包含对 'a' 的引用。返回的对 'a' 的引用将被视为'新',因此 X 将从 MM 中提取它。

But is there a problem with my second point?但是我的第二点有问题吗? Maybe I misunderstand the memory model.也许我误解了 memory model。

The thread X safely publishes the object a to thread Y and does not do any modification until Y succeeds.线程 X 安全地将 object a发布到线程 Y 并且在 Y 成功之前不做任何修改。 So the object a is safely published from thread X to thread Y.所以 object a从线程 X 安全地发布到线程 Y。

Moreover, All actions in a thread happen-before any other thread successfully returns from a Future.get() on that thread.此外,线程中的所有操作都发生在任何其他线程从该线程上的Future.get()成功返回之前。 Upon returning from Future.get() thread X can see all the changes made by thread Y to the object a .Future.get()返回后,线程 X 可以看到线程 Y 对 object a所做的所有更改。

So according to our thread safety analysis, we can conclude that this code is thread safe.所以根据我们的线程安全分析,我们可以断定这段代码是线程安全的。

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

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