Я прочел несколько объяснений , раздел 16.3 «Инициализация безопасности» от JCIP и до сих пор не ясен. В разделе указывается, чтоДоступность видимости
«Кроме того, любые переменные, которые могут быть достигнуты через конечное поле правильно построенного объекта (например, элементы конечного массива или содержимое HashMap, на которое ссылается конечное поле), также гарантированно быть видимым для других потоков ».
Так что, если я имел следующий изменяемый объект:
public final class Container{
private String name;
private int cupsWon;
private double netWorth;
public Container(String name, int cupsWon, double netWorth){
this.name = name;
this.cupsWon = cupsWon;
this.netWorth = netWorth;
}
//NO Setters
//Getters
}
Затем Thread 1 создает его следующим образом и проходит с к thread2.
final Container c = new Container("Ted Dibiasi", 10, 1000000);
Резьба2 (не одновременно, позволяет сказать, что через 1 мс), считывает значения с, возможно, что Резьба2 никогда не увидит
c.name=null or
c.cupswon=0 or worst of all,
c.netWorth=0.0?
Приветствия
UPDATE
Я заметил, что в классе есть геттеры. Я обновляю исходный код, надеюсь, это будет ясно. Спасибо, что посмотрели.
public final class Container{
private String name;
private int cupsWon;
private double netWorth;
public Container(String name, int cupsWon, double netWorth){
this.name = name;
this.cupsWon = cupsWon;
this.netWorth = netWorth;
}
public final String getName(){
return name;
}
public final int getCupsWon(){
return cupsWon;
}
public final double getNetWorth(){
return netWorth;
}
}
// ----------
public final class Producer{
private final Client client;
public Producer(Client client){
this.client = client;
}
//Thread1 call produce()
public final void produce(){
final Container c = new Container("Ted Dibiasi", 10, 1000000);
client.update(c);
}
}
// ----
public final class Client{
private Container c;
//private volatile Container c;
public final void update(Container c){
this.c = c;
}
//Thread2 calls consume().
public final void consume(){
String name = c.getName();
int cupsWon = c.getCupsWon();
double netWorth = c.getNetWorth();
}
}
Мои вопросы:
а) Когда Thread2 calls calls(), можно назвать, cupsWon, netWorth когда-либо равным null, 0 или 0.0? Я думал, что это CAN потому что поскольку поля в Container не являются окончательными, нет гарантии видимости.
б) Тем не менее, потом я прочитал раздел 16.3 и бит о «переменных, которые могут быть достигнуты с помощью конечного поля правильно построенного объекта», это означает, что, поскольку экземпляр контейнера С объявляется окончательным, есть DO есть осмотр на доступность в потреблении()?
final Контейнер c = новый контейнер («Ted Dibiasi», 10, 1000000);
c) Объявление ссылки на Container в классе Client как изменчивое решение не разрешает проблему видимости полей, поскольку она относится к ссылке.
Поскольку строительство произошло до того, как оно было передано (как оно может быть принято иначе, в первую очередь?), Я предполагаю, что это невозможно. – MirMasej
Можете ли вы прояснить, есть ли геттеры или нет? Я думаю, вы имеете в виду, что есть _ get_ getters, но _no_ сеттеры, тогда как есть ответ, который предполагает, что нет. – hiergiltdiestfu
@hiergiltdiestfu Да, есть геттеры, но нет сеттеров. – CaptainHastings