Я полагаю, что читатели, разбирающиеся в многопоточности Java, ясно поймут ее роль. Ключевое слово Летучий используется для объявления переменных простого типа, таких как int, float, boolean и другие типы данных. Если эти простые типы данных объявлены изменчивыми, операции над ними становятся атомарными. Но это имеет определенные ограничения. Например, n в следующем примере не является атомарным:
Скопируйте код кода следующим образом:
пакет мифрид;
публичный класс JoinThread расширяет поток
{
общественный статический изменчивый int n = 0;
публичный недействительный запуск()
{
для (int я = 0; я <10; я++)
пытаться
{
п = п + 1;
Sleep(3); // Чтобы сделать результаты выполнения более случайными, задержите 3 миллисекунды;
}
поймать (Исключение e)
{
}
}
public static void main(String[] args) выдает исключение
{
Потоки [] = новая тема [100];
for (int i = 0; i < threads.length; i++)
// Создаем 100 потоков
потоки [я] = новый JoinThread();
for (int i = 0; i < threads.length; i++)
//Запускаем 100 только что созданных потоков
потоки[i].start();
for (int i = 0; i < threads.length; i++)
//Продолжить после выполнения всех 100 потоков
потоки[i].join();
System.out.println("n=" + JoinThread.n);
}
}
Если операция над n является атомарной, конечный результат вывода должен быть n=1000. Однако при выполнении вышеуказанного кода города выходное значение n часто меньше 1000, что показывает, что n=n+1 не является операцией атомарного уровня. . Причина в том, что для простой переменной, объявленной изменчивой, если текущее значение связано с предыдущим значением переменной, то ключевое слово изменчивости не имеет никакого эффекта, а это означает, что следующие выражения не являются атомарными операциями:
Скопируйте код кода следующим образом:
п = п + 1;
н++;
Если вы хотите сделать эту ситуацию атомарной операцией, вам нужно использовать ключевое словоsynchronized. Приведенный выше код можно изменить на следующую форму:
Скопируйте код кода следующим образом:
пакет мифрид;
публичный класс JoinThread расширяет поток
{
общественный статический int n = 0;
публичная статическая синхронизация void inc()
{
н++;
}
публичный недействительный запуск()
{
для (int я = 0; я <10; я++)
пытаться
{
inc(); // n = n + 1 изменено на inc();
Sleep(3); // Чтобы сделать результаты выполнения более случайными, задержите 3 миллисекунды;
}
поймать (Исключение e)
{
}
}
public static void main(String[] args) выдает исключение
{
Потоки [] = новая тема [100];
for (int i = 0; i < threads.length; i++)
// Создаем 100 потоков
потоки [я] = новый JoinThread();
for (int i = 0; i < threads.length; i++)
//Запускаем 100 только что созданных потоков
потоки[i].start();
for (int i = 0; i < threads.length; i++)
//Продолжить после выполнения всех 100 потоков
потоки[i].join();
System.out.println("n=" + JoinThread.n);
}
}
Приведенный выше код заменяет n=n+1 на inc(), где метод inc использует ключевое слово Synchronized для синхронизации методов. Поэтому будьте осторожны при использовании ключевого слова Летучего. Это не означает, что переменные простого типа изменяются с помощью летучих. Все операции с этой переменной являются исходными операциями, когда значение переменной определяется ее предыдущей, например n=. n+1 , n++ и т. д., ключевое слово Volatible будет недопустимым. Операция над переменной является атомарной только в том случае, если значение переменной не имеет ничего общего с ее предыдущим значением. Например, n = m + 1, это. это исходный уровень. Поэтому вы должны быть осторожны при использовании энергозависимых ключей. Если вы не уверены, вы можете использовать синхронизированные ключи вместо энергозависимых.