【问题标题】:Thread populating collection and Java memory model线程填充集合和 Java 内存模型
【发布时间】:2020-07-21 10:05:36
【问题描述】:

我注意到,如果我让一个线程填充一个集合,在join 之后的线程末尾,我会看到该集合按预期填充。

关于 Java 内存模型,这是否总能保证发生?

如果线程将列表中对象的引用存储在 cpu 缓存中怎么办?
在这种情况下,加入后加入线程必须保证看到更改?

final ArrayList<Person> persons = new ArrayList();
Thread myThread = new MyThread(persons);
myThread.start();
myThread.join();

// persons ?

线程

public class MyThread extends Thread {
    
    ArrayList<Person> persons;

    public MyThread(ArrayList<Person> persons){
     this.persons = persons;
    }

    public void run(){
      persons.add(new Person(...))
      // add more
    }
  }

【问题讨论】:

  • join一个线程建立了一个happens-before。

标签: java multithreading collections thread-safety


【解决方案1】:

是的,这是由内存模型保证的。

  • start() 调用和子线程的run() 方法的第一个动作之间有一个发生

  • 在子线程的最后一个操作(任何类型的)和父线程中返回的join() 之间有一个发生之前

这是在JLS 17.4.5中指定的

这些足以确保子线程看到一个正确初始化的列表,而父线程看到一个正确填充的列表......在join()之后。

【讨论】:

    【解决方案2】:

    来自Java Language Specification § 17.4.5

    ...
    线程中的所有操作发生之前任何其他线程成功地从该线程上的join() 返回。
    ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-02
      • 2013-12-31
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多