Являются примитивными типами данных потокобезопасными в Java
Являются ли примитивные типы данных типа int
и short
потокобезопасными в Java? Я выполнил следующий код и не мог видеть ожидаемый результат 500 несколько раз.
public class SampleThree extends Thread
{
static long wakeUpTime = System.currentTimeMillis() + (1000*20);
static int inT;
public static void main(String args[])
{
System.out.println("initial:" + inT);
for(int i=0; i<500; i++)
new SampleThree().start();
try {
Thread.sleep(wakeUpTime - System.currentTimeMillis() + (1000*30));
System.out.println("o/p:" + inT);
}
catch(Exception e){
e.printStackTrace();
}
}
public void run()
{
try {
long s = wakeUpTime - System.currentTimeMillis();
System.out.println("will sleep ms: " + s);
Thread.sleep(s);
inT++; // System.out.println(inT);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Здесь параллельно поток 500 будет обновлять переменную int int
. Главный поток после ожидания завершения параллельного обновления, выводит int
значение.
Найдите аналогичный пример здесь
Ответы
Ответ 1
Есть три способа, которыми они не безопасны:
-
long
и double
даже не гарантированно обновляются атомарно (вы можете увидеть половину записи из другого потока)
- Модель памяти не гарантирует, что вы увидите последние обновления из одного потока в другом потоке без каких-либо дополнительных барьеров памяти.
- Акт приращения переменной в любом случае не является атомарным
Используйте AtomicInteger
и т.д. для поточно-безопасных операций.
Ответ 2
Примитивные типы не являются потокобезопасными. Проверьте этот учебник.
Ответ 3
Я бы предложил использовать классы в java.util.concurrent.atomic. Они предназначены для обеспечения безопасности потоков, а в некоторых случаях JVM может использовать аппаратные функции для оптимизации.