Раньше я считал, что любая переменная, совместно используемая двумя потоками, может кэшироваться локально в потоке и должна быть объявлена как volatile. Но это убеждение недавно было оспорено товарищем по команде. Мы пытаемся выяснить, требуется ли volatile в следующем случае или нет.
class Class1
{
void Method1()
{
Worker worker = new Worker();
worker.start();
...
System.out.println(worker.value); // want to poll value at this instant
...
}
class Worker extends Thread
{
int value = 0; // Should this be declared as a volatile?
public void run()
{
...
value = 1; // this is the only piece of code that updates value
...
}
}
}
Теперь я утверждаю, что рабочий (дочерний) поток мог кэшировать переменную «значение» объекта Worker в потоке и обновлять только его копию, устанавливая значение 1. В таком случае , основной поток может не увидеть обновленное значение.
Но мой товарищ по команде считает, что, поскольку доступ к «значению» происходит через объект (рабочий процесс), поэтому оба потока могут видеть разные значения, это возможно только в том случае, если оба потока поддерживают отдельные копии «рабочего процесса». сам объект (что также означает, что создание потока включает в себя создание глубокой копии всех общих объектов).
Теперь я знаю, что это не может быть правдой, поскольку для каждого потока было бы крайне неэффективно поддерживать совершенно разные копии всех совместно используемых объектов. Поэтому я в большом сомнении. Делает ли «worker.value» в основном потоке ссылку на другое место в памяти, чем выполнение «this.value» в дочернем потоке? Будет ли дочерний (рабочий) поток кэшировать «значение»?
С уважением.