[concurrency-interest] do constructors ever involve threading under the covers?

Aleksey Shipilev aleksey.shipilev at oracle.com
Wed Oct 3 10:44:34 EDT 2012


On 10/03/2012 06:22 PM, Andy Nuss wrote:
> So if I follow you correctly, for a constructor that has an array or
> ArrayList member, creates that array/ArrayList, and fills it with a
> bunch of seeded values, which are effectively final: another thread will
> not see the values in the array/ArrayList unless the constructed object
> is "published" to the other thread, such as with a volatile variable or
> concurrent map.

If you are reading those "seeded" values from somewhere else, then there
is no guarantees you will read the actual values in the constructor
unless you take the precaution of publishing those values safely. If you
are populating the list in the constructor with generated values and
store it in the field, then you are fine:

public class A {
    private final List<Integer> list;
    public A() {
        list = new ArrayList<>();
        list.add(1); list.add(2); list.add(3);

// everything is visible
List<Integer> l = new A().list;


private int myRogueField;

public class B {
    private final List<Integer> list;
    public B() {
        list = new ArrayList<>();

// no guarantees actual $myRogueField value is there
List<Integer> l = new B().list;


private volatile int myAwesomeField;

public class C {
    private final List<Integer> list;
    public C() {
        list = new ArrayList<>();

// extra care was given when reading $myAwesomeField
// guaranteed to be visible in the list.
List<Integer> l = new C().list;


Note that you have to make sure you *read* the correct values when
passing those to the constructor. Target constructor itself could not
enforce this.

> In that case, can someone explain to me how java String, which holds an
> array of characters, is threadsafe without the need for publishing the
> string to the other thread?  I.e. even if the array reference is final,
> the "final" attribute does not apply to the elements of the array.  Same
> with a final ArrayList reference.

Sorry, can't see the problem.

String is immutable, you can not write into the backing char[] array
there. Once string is created, it copies the contents into its own array
(modulo contrived cases of subString()) in constructor, gets everything
freezed as required by JMM, and uses the array then. If you are
providing the String with safely-acquired source char[] array, it goes
the "class A" as described above.


More information about the Concurrency-interest mailing list