Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Общие вопросы по Java, Java SE, Kotlin
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.03.2018, 20:55   #1
datgen
Пользователь
 
Регистрация: 30.03.2011
Сообщений: 36
По умолчанию разобраться с volatile

Добрый вечер.
Нашел такой пример и в нем действительно без volatile потоки не останавливаются

Код:
public class VolatileDemo {
    // вначале попробуйте без volatile
     volatile private boolean btExit = false;
     volatile private boolean isRunning = true;

    // задача для интерфейсного потока
    Runnable gui = new Runnable() {

        @Override
        public void run() {
            int k=-1;
            while (isRunning) {
                try {
                    k = System.in.read() ;
                    btExit = k>=0;
                    System.out.println("gui input: "+k);
                } catch (Exception e) {
                }
            }
            System.out.println("gui thread finished");
        }
    };

    // задача для игрового потока
    Runnable game = new Runnable() {

        @Override
        public void run() {
            int k=1;
            while (!btExit) {
                k+=k;
                k%=100;
                // System.out.print("");
            }
            isRunning=false;
            System.out.println("game thread finished");
        }
    };

    // запуск потоков
    public void start() {
        new Thread(gui).start();
        new Thread(game).start();
    }


    // чтобы остановить программу запущенную без volatile и без System.out.print(""); в игровом цикле
    // в Eclipse в окне консоли кликните на красный квадрат
    public static void main(String[] args) {
        new VolatileDemo().start();
    }
}
я написал такой пример, проясните кто нибудь почему тут без volatile все работает
Код:
class Task2{

    private boolean b = false;

    Runnable runnable1 = new Runnable() {
        @Override
        public void run() {
            while (!b) {
                try {
                    System.out.println("+");
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    Runnable runnable2 = new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(500);
                b = true;
            } catch (InterruptedException e) {
            }
        }
    };

    public void start() {
        new Thread(runnable1).start();
        new Thread(runnable2).start();
    }
}
datgen вне форума Ответить с цитированием
Старый 08.03.2018, 21:04   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Потому что тут есть запись и компилятор это заметил, и не стал кэшировать.
p51x вне форума Ответить с цитированием
Старый 08.03.2018, 21:04   #3
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Thread.sleep(500);

скорее всего, но все равно там ничего не гарантиравано без volatile. Что-то измените и все сломается.
Кросс-потоковое общение должно быть обязательно синхронизировано неким способом (там их несколько), в яве 1 из них volatile.

Вообще, отстутствие явной верной сихронизации м-у потоками так и проявляется - случайно что-то не так. Например, на 1 процессоре все ок, на 4 процессорах - все сломалось не понять как. Т.е. как только полезло "не понять что", начинаем проверять все между-поточные передачи данных и делать их верно синхронными.

Последний раз редактировалось alexzk; 08.03.2018 в 21:09.
alexzk вне форума Ответить с цитированием
Старый 08.03.2018, 21:12   #4
datgen
Пользователь
 
Регистрация: 30.03.2011
Сообщений: 36
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Потому что тут есть запись и компилятор это заметил, и не стал кэшировать.
можно тут чуть подробнее пожалуйста
datgen вне форума Ответить с цитированием
Старый 08.03.2018, 23:31   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Кросс-потоковое общение должно быть обязательно синхронизировано неким способом (там их несколько), в яве 1 из них volatile.
я бы не назвал volatile синхронизацией.
volatile говорит компилятору что значение может изменится в ином потоке, он отключает кеширование результата обращения.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 09.03.2018, 01:29   #6
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
я бы не назвал volatile синхронизацией.
volatile говорит компилятору что значение может изменится в ином потоке, он отключает кеширование результата обращения.
Это скорее вы про С++ говорите
http://alenacpp.blogspot.com/2006/04/volatile.html
где ничего как раз не гарантируется - т.е. просто не оптимизируем и все.

А вот в яве
https://ru.stackoverflow.com/questio...le-%D0%B2-java

это уже атомарная операция.

Но лично я всегда делал так:

private final AtomicBoolean isSome = new AtomicBoolean(false);
alexzk вне форума Ответить с цитированием
Старый 09.03.2018, 02:32   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

главное это пункт 2 ответа, а не 1.

без этого модификатора, компилятор/JIT может оптимизировать чтение, это и в Java мире так же.
атомарность уже отличается, да(в С++ не гарантируется к примеру)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 09.03.2018 в 02:35.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
volatile 220Volt Общие вопросы C/C++ 8 08.02.2013 08:44
Объясните разницу модификаторов CONST и VOLATILE svatorus Помощь студентам 0 07.06.2012 13:13
Разобраться Nempak Общие вопросы C/C++ 2 27.03.2011 14:06
Interlocked-функции и volatile. Необходимость совместного использования. neokoder Win Api 0 21.03.2011 22:06