Вопрос проверяет понимание изоляции потоков и того, почему локальные переменные и контекст выполнения не должны смешиваться между потоками.
У каждого потока свой stack, потому что каждый поток выполняет свой набор вызовов методов.
В стеке хранятся локальные переменные и состояние выполнения, которое нельзя разделять между потоками.
Если бы стек был общий, потоки мешали бы друг другу и ломали бы выполнение методов.
Раздельный стек обеспечивает изоляцию и безопасность выполнения.
Каждый поток в JVM — это независимая «линия выполнения», и ей нужен свой собственный контекст.
Отдельный stack на поток — это механизм изоляции выполнения: каждый поток хранит свои stack frames независимо от других.
Стек хранит данные, которые относятся к конкретному потоку:
Цепочку вызовов методов
Параметры и локальные переменные
Временные значения вычислений
Точки возврата (куда вернуться после вызова)
Все это уникально для потока, потому что потоки выполняют разный код и в разное время.
Если представить общий стек на все потоки, возникли бы проблемы:
Поток A положил frame метода foo()
Поток B положил поверх frame метода bar()
Поток A продолжает выполнение, но стек уже «испорчен» чужими кадрами
Возвраты из методов и локальные переменные начинают путаться
Итог:
Непредсказуемое поведение
Краш JVM
Полная невозможность гарантировать корректность
Раздельные стеки дают естественную безопасность:
Локальные переменные одного потока недоступны другому напрямую
Вызовы методов не пересекаются
GC Roots для потока включают его стек, поэтому достижимость считается корректно
В двух потоках может быть одинаковое имя переменной x, но это разные переменные в разных стеках:
void work() {
int x = 10; // локальная переменная конкретного потока
}
Каждый поток получит свой x.
У каждого потока свой stack, потому что стек — это контекст выполнения, который нельзя безопасно разделять.
Это обеспечивает изоляцию, корректные вызовы методов и базовую потокобезопасность локальных данных.