在 Java 中,基元数据类型是线程安全的吗?

2022-09-01 03:36:19

在Java中,像&thread-safe这样的原始数据类型是安全的吗?我已经执行了以下代码,但有时看不到预期的结果500。intshort

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变量。主线程等待并发更新完成后,打印值。inTinT

在此处查找类似示例


答案 1

它们有三种不安全的方式:

  • long甚至不能保证以原子方式更新(您可以看到来自其他线程的一半写入)double
  • 内存模型不保证您将在另一个线程中看到来自另一个线程的最新更新,而不会出现某种额外的内存障碍
  • 无论如何,递增变量的行为都不是原子的

使用 AtomicInteger 等进行线程安全操作。


答案 2

基元类型不是线程安全的。查看本教程