public class Solution {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new TestThread());
t.start();
Thread.sleep(3000);
ourInterruptMethod();
}
public static volatile boolean isInterrupted=false;
public static void ourInterruptMethod() {
isInterrupted=true;
}
public static class TestThread implements Runnable {
public void run() {
while (!isInterrupted) {
try {
System.out.println("he-he");
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
}
По моим представлениям переменная isInterrupted должна быть обязательно volatile. Так как обращение к ней идет из TestThread, а изменение в main. Это ведь долны быть две разные переменные для каждого потока, но работает и без модификатора и с ним. Подскажите, в чем делоAnastasia Ilyushenko
34 уровень
Про модификатор volatile
Решен
Комментарии (7)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Nikita Zayakin
23 октября 2018, 19:45
Когда решал задачу, про этот момент не подумал. Работает без ключевого слова volatile у переменной. И действительно непонятно, как работает-то? Кто-то из подкованных людей знает технически грамотный и подробный ответ?
0
Илья ГековMaster
19 августа 2018, 18:21решение
Одна нить изменяет, вторая лишь читает , в чем может быть проблема в данном случае? Volatile просто не дает заносить значение переменной в кеш, а заставляет сразу кидать значение в память, в данном случае не происходит никаких коллизий, одна нить в бесконечном цикле проверяет значение переменной, вторая это значение изменяет.
Если бы они пытались одновременно изменять пеоеменную (например увеличивать один счетчик на двоих), то без волатайл рано или поздно произошел бы сбой в подсчете, из-за кеширования значения этой переменной.
+5
Nikita Zayakin
23 октября 2018, 19:42
А тут вроде два потока, у каждого свой кэш. И получается, что один поток (Main) поменял переменную, в своем кэше. Но без volatile, по идее-то нет гарантии, что эта переменная обновится в кэше второго потока (Thread-0). Так каким образом, гарантированно происходит изменение переменной в кэше другого потока при отсутсвии ключевого слова volatile у такой переменной, непонятно.
0
Nikita Zayakin
23 октября 2018, 19:49
Закралась догадка, что если поток (Thread-1) не изменяет внутри себя значение переменной, а только читает ее, то видимо этот поток ее не кэширует, и таким образом она считывается из кэша главного потока (Main). Так?
0
Илья ГековMaster
23 октября 2018, 19:52
Кеширование происходит для оптимизации, сохранения значения переменной для последующих операций с ней. В данном случае из main меняется значение переменной isInterrupted один раз и всё, действия с ней закончились, значение попадет в память (оно же не будет удерживаться в кеше, непонятно зачем). Так как второй поток в бесконечном цикле проверяет это значение, то он увидит это изменение, если не в ту же, скажем, миллисекунду, в которую это изменение произошло, то в следующую (условно говоря, досконально процессы происходящие в процессорах я к сожалению не знаю).
+1
Nikita Zayakin
23 октября 2018, 19:56
Ого, оперативный ответ -). Спасибо! Примерно понятно. Однако еще интересует, как можно разобраться в процессе поподробней!
0
Илья ГековMaster
23 октября 2018, 19:58
Могу посоветовать лекции Ивана Головача на ютубе, там в принципе много по Java Core, есть блок лекций по многопоточности, мне очень помогли в понимании
+3