线程填充集合和Java内存模型

huangapple go评论55阅读模式
英文:

Thread populating collection and Java memory model

问题

我注意到,如果我让一个线程填充一个集合,在线程的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(...))
        // 添加更多
    }
}
英文:

I noticed that If I let a thread populate a collection, at the end of the thread after the join, I see the collection populated as expected.

In respect to the Java memory model, is this always guaranteed to happen ?

what if the thread is storing the references of the objects in the list in the cpu cache ?
In this case after the join the joining thread would have to guarantee to see the changes ?

final ArrayList&lt;Person&gt; persons = new ArrayList();
Thread myThread = new MyThread(persons);
myThread.start();
myThread.join();

// persons ?

Thread

public class MyThread extends Thread {
    
    ArrayList&lt;Person&gt; persons;

    public MyThread(ArrayList&lt;Person&gt; persons){
     this.persons = persons;
    }

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

答案1

得分: 6

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

  • start()调用和子线程的run()方法的第一个动作之间存在happens before

  • 在子线程的任何类型的最后一个动作和父线程中join()返回之间存在happens before

这在JLS 17.4.5中有详细规定。

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

英文:

Yes, it is guaranteed by the memory model.

  • There is a happens before between the start() call and the first action of the child thread's run() method.

  • There is a happens before between the last action (of any kind) of the child thread and the join() returning in the parent thread.

This is specified in JLS 17.4.5

These are sufficient to ensure that the child thread sees a properly initialized list and the parent thread sees a correctly populated list ... after the join().

答案2

得分: 4

From the Java Language Specification § 17.4.5

> 所有线程中的所有操作在任何其他线程成功从该线程的 join() 返回之前都会先行发生
> ...

英文:

From the Java Language Specification § 17.4.5

> ...
> All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
> ...

huangapple
  • 本文由 发表于 2020年7月21日 18:05:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63012137.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定