Criação de objetos de simultaneidade em Java

Estou lendo um livro "Simultaneidade de Java na prática", de Brian Goetz. Os parágrafos 3.5 e 3.5.1 contêm declarações que não consigo entender.

Considere o seguinte código:

public class Holder {
  private int value;
    public Holder(int value) { 
    this.value = value;
  }

  public void assertValue() {
    if (value != value) throw new AssertionError("Magic");
  }
}

class HolderContainer {
  // Unsafe publication
  public Holder holder;

  public void init() {
    holder = new Holder(42);  
  }
}

O autor afirma que:

Em Java, o construtor Object primeiro grava valores padrão em todos os campos antes da execução do construtor da subclasse.Portanto, é possível ver o valor padrão do campo como um valor obsoleto.O encadeamento pode ver um valor obsoleto na primeira vez em que lê um campo e, em seguida, um valor mais atualizado na próxima vez, e é por isso que assertN pode lançar AssertionError.

Assim, de acordo com o texto, com algum tempo de azar, é possível que o valor = 0; e no momento seguinte valor = 42.

Concordo com o ponto 1, que o construtor Object preenche os campos com valores padrão. Mas eu não entendo os pontos 2 e 3.

Vamos atualizar o código dos autores e considerar o seguinte exemplo:

public class Holder {
  int value;

  public Holder(int value) {
    //Sleep to prevent constructor to finish too early
    try {
     Thread.sleep(3000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    this.value = value;
  }

  public void assertValue()  {
    if(value != value) System.out.println("Magic");
  }
}

Adicionei Thread.sleep (3000), para forçar o thread a aguardar antes que o objeto seja totalmente construído.

public class Tests {

  private HolderContainer hc = new HolderContainer();

  class Initialization implements Runnable {
    public void run() {
      hc.init();
    }
  }

  class Checking implements Runnable {
    public void run() {
      hc.holder.assertValue();
    }
  }

  public void run() {
    new Thread(new Initialization()).start();
    new Thread(new Checking()).start();
  }
}

No exemplo:

primeiro objeto de suporte de inits de roscao segundo thread chama assertValue

O thread principal executa dois threads:

novo thread (nova inicialização ()). start (); Demorou 3 segundos para construir totalmente o objeto Holdernovo thread (nova verificação ()). start (); como o objeto Holder ainda não construído, o código lançará umNull Pointer Exception

Portanto, é impossível emular a situação quando o campo tem valor padrão.

Minhas perguntas:

O autor estava errado sobre esse problema de simultaneidade?Ou é impossível emular o comportamento dos valores padrão dos campos?

questionAnswers(3)

yourAnswerToTheQuestion