Я читал параллелизм в действии и имел пару вопросов.Безопасность нити/публикация
public final class ThreeStooges {
private final Set<String> stooges = new HashSet<String>();
public ThreeStooges() {
stooges.add("Moe");
stooges.add("Larry");
stooges.add("Curly");
}
public boolean isStooge(String name) {
return stooges.contains(name);
}
}
В книге говорится, что, поскольку этот класс является неизменяемым это поточно, так как нет никакого изменения состояния (Stooges). Я смущен этим. Что делать, если несколько потоков должны были вызвать метод isStooge (String name) одновременно. Что происходит?
public class HolderObject{
private Holder holder;
public void initialize() {
holder = new Holder(42);
}
}
В книге говорится, что это не потолочный сейф? Зачем? Что значит, что он не опубликован должным образом?
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n)
throw new AssertionError("This statement is false.");
}
}
То же самое и с этим. Что с этим не так? Что делать, если несколько потоков звонят assertSanity()
.
Спасибо ребята
UPDATE
Скажем, класс приспешники изменяется на следующий ...
public class ThreeStooges {
private List<String> stooges = new ArrayList<String>();
public ThreeStooges() {
stooges.add("Moe");
stooges.add("Larry");
stooges.add("Curly");
}
public synchronized void addStoog(String stoog){
stooges.add(stoog);
}
public boolean getStoog(int index){
return stooges.get(index);
}
public boolean isStooge(String name) {
return stooges.contains(name);
}
}
Есть ли какие-либо проблемы нить здесь? Проблемы с видимостью на геттерах? Если поток A был для addStoog («Bobby») и Thread B вызывает getStoog (3), будет ли последний мачеха видна на геттере?
Оба вы, ребята, были большой помощью, но я не могу отметить оба. Я также не могу повышать, потому что у меня меньше 15 человек. – user1172490
+1 И спасибо за объяснение третьего примера. Один следующий вопрос здесь: может ли эта гонка все же произойти, если есть связь между вызовом конструктора 'Holder' и вызовом функции' assertSanity'? Я спрашиваю, потому что в общем случае, если у вас есть расы между завершением выполнения конструктора и вызовами функций-членов, у вас обычно возникают еще большие проблемы, поскольку инварианты класса могут быть не установлены при выполнении функций-членов. – ComicSansMS
Я думаю, что по спецификации Java 5 модель памяти изменилась, чтобы позволить конструктору полностью закончить, прежде чем можно будет вызвать другие методы.Я не знаю, если я на 100% прав. Здесь нужен эксперт. – user1172490