Если доступ к общим изменяемым данным не может быть синхронизирован, последствия могут быть ужасными, даже если переменная доступна для атомарного чтения и записи.
Давайте рассмотрим проблему синхронизации потоков. Для синхронизации потоков библиотека классов Java предоставляет метод Thread.stop, но этот метод не стоит продвигать, поскольку он по своей сути небезопасен. Лучше было бы использовать опрос, например, следующую программу.
Скопируйте код кода следующим образом:
импортировать java.util.concurrent.TimeUnit;
общественный класс StopThread {
/**
* @param аргументы
*/
частное статическое логическое значение stopRequested;
public static void main(String[] args)
выдает InterruptedException{
Поток backgroundThread = новый поток (новый Runnable () {
@Override
общественный недействительный запуск () {
интервал я = 0;
в то время как (! stopRequested) {
я++;
System.out.println(я);
}
}
});
фоновый поток.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = правда;
}
}
Вы можете подумать, что после того, как эта программа проработает около одной секунды, основной поток установит для stopRequested значение true, что приведет к остановке нового фонового потока. На самом деле это не так, поскольку фоновый поток не может видеть изменения в этом. значение, поэтому цикл будет продолжаться бесконечно, это следствие отсутствия синхронизации данных. Итак, давайте сделаем это синхронно.
Скопируйте код кода следующим образом:
импортировать java.util.concurrent.TimeUnit;
общественный класс StopThread {
/**
* @param аргументы
*/
частное статическое логическое значение stopRequested;
частный статический синхронизированный void requestStop(){
stopRequested = правда;
}
частная статическая синхронизированная логическая функция stopRequested(){
вернуть стоп-запрос;
}
public static void main(String[] args)
выдает InterruptedException {
Поток backgroundThread = новый поток (новый Runnable () {
@Override
общественный недействительный запуск () {
интервал я = 0;
while(!stopRequested()){
я++;
System.out.println(я);
}
}
});
фоновый поток.start();
TimeUnit.SECONDS.sleep(1);
запросСтоп();
}
}
Тем самым достигается синхронизация данных. Стоит отметить, что и метод записи (requestStop), и метод чтения (stopRequested) должны быть синхронизированы, иначе они все равно не будут синхронизированы в истинном смысле.
Кроме того, мы можем использовать модификатор изменчивой переменной для более простого выполнения задач синхронизации.
Скопируйте код кода следующим образом:
импортировать java.util.concurrent.TimeUnit;
общественный класс StopThread {
/**
* @param аргументы
*/
частный статический изменчивый логический stopRequested;
public static void main(String[] args)
выдает InterruptedException {
Поток backgroundThread = новый поток (новый Runnable () {
@Override
общественный недействительный запуск () {
интервал я = 0;
в то время как (! stopRequested) {
я++;
System.out.println(я);
}
}
});
фоновый поток.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = правда;
}
}