tg-me.com/javatg/1855
Last Update:
🧠 Java-задача: "Immutable? Не совсем…"
📜 Условие:
У тебя есть якобы *immutable* класс:
public class Point {
public final int x;
public final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
И следующий код:
public class Main {
static Point shared;
public static void main(String[] args) throws InterruptedException {
Thread writer = new Thread(() -> {
shared = new Point(1, 2);
});
Thread reader = new Thread(() -> {
Point p = shared;
if (p != null) {
System.out.println("x = " + p.x + ", y = " + p.y);
}
});
writer.start();
writer.join();
reader.start();
reader.join();
}
}
❓ Вопрос:
1. Могут ли быть выведены "x = 1, y = 0" или даже "x = 0, y = 0"?
2. Почему?
x
и y
ведь final
— разве этого недостаточно? 3. Как гарантировать корректность и видимость всех полей в многопоточной среде?
⚠️ Подвох:
- В Java Memory Model (`JMM`) даже `final` поля не дают полной гарантии видимости, если объект передаётся между потоками без синхронизации.
- Поток
reader
может увидеть частично сконструированный объект:- Конструктор не завершился, а
shared
уже указывает на объект.- Это не баг JVM, а результат слабых гарантий
JMM
без синхронизации.✅ Правильный ответ:
Да, такой результат возможен —
reader
может увидеть x = 1
, y = 0
, или даже x = 0
, y = 0
.🛡️ Как защититься:
- Сделать
shared
volatile, или- Передавать объект через synchronized блоки,
Lock
, AtomicReference
, CountDownLatch
, Thread-safe очередь
, и т.д.
static volatile Point shared;
🎯 Чему учит задача:
• Знание Java Memory Model (JMM)
• Понимание, что
final != synchronized
• Почему даже "immutable" объекты могут стать "опасно mutating"
• Умение писать багоустойчивый многопоточный код
@javatg
BY Java
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
Share with your friend now:
tg-me.com/javatg/1855