线程安全问题

java并发编程学习之基础概念提到,多线程的劣势之一,有个线程安全问题,现在看看下面的例子。

public class Unsafe {
    private int i;

    public int getNext() {
        return i++;
    }

    public int getI() {
        return i;
    }

    static class Thread1 extends Thread {
        Unsafe unsafe;

        public Thread1(Unsafe unsafe) {
            this.unsafe = unsafe;
        }

        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                unsafe.getNext();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Unsafe unsafe = new Unsafe();
        List<Thread1> threads = new ArrayList<>(1000);
        for (int i = 0; i < 1000; i++) {
            Thread1 thread1 = new Thread1(unsafe);
            threads.add(thread1);
            thread1.start();
        }
        for (int i = 0; i < threads.size(); i++) {
            threads.get(i).join();
        }
        System.out.println(unsafe.getI());
    }
}

运行结果如下:
clipboard.png

结果小于10万。为什么会不安全呢,在java并发编程学习之基础概念提过,两个线程共享一个进程的资源。比如第一个线程获取到的值是0,这时候,把值放在寄存器,在cpu运算后,结果1放入寄存器,再存入内存。此时另外一个线程也获取0,cpu计算后,也是1,就覆盖原来的内存,所以i++两次后,还是1,少加了一次。


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆