并发线程安全的AtomicInteger

时间:2015-03-20 12:08:52

标签: java multithreading concurrency atomicinteger

我已经阅读了java.util.concurrent包的API文档,但显然有些误解了。概述说

  

支持无锁线程安全的小型工具包   对单个变量进行编程。

但是,一个小的测试应用程序显示AtomicInteger类不提供线程安全性,至少在跨线程共享时(我接受getAndSet / increment方法本身至少原子

测试:

import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntTest
{
    public static void main(String[] args) throws InterruptedException
    {
        AtomicInteger atomicInt = new AtomicInteger(0);
        WorkerThread w1 = new WorkerThread(atomicInt);
        WorkerThread w2 = new WorkerThread(atomicInt);
        w1.start();
        w2.start();
        w2.join(); // <-- As pointed out by StuartLC and BarrySW19, this should be w1.join(). This typo allows the program to produce variable results because it does not correctly wait for *both* threads to finish before outputting a result.
        w2.join();
        System.out.println("Final value: " + atomicInt.get());
    }

    public static class WorkerThread extends Thread
    {
        private AtomicInteger atomicInt = null;
        private Random random = new Random();

        public WorkerThread(AtomicInteger atomicInt)
        {
            this.atomicInt = atomicInt;
        }

        @Override
        public void run()
        {
            for (int i = 0; i < 500; i++)
            {
                this.atomicInt.incrementAndGet();
                try
                {
                    Thread.sleep(this.random.nextInt(50));
                }
                catch(InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

当我上课时,我总是得到大约950到1000的结果,当我希望总能看到1000时。

当两个线程访问这个共享的AtomicInteger变量时,你能解释为什么我得不到一致的结果吗?我是否误解了线程安全保障?

1 个答案:

答案 0 :(得分:1)

看起来像一个简单的剪切和粘贴错误 - 您正在加入线程&#34; w2&#34;两次,永远不会&#34; w1&#34;。目前,你会期待线程&#34; w1&#34;打印“#final”时,仍然有一半的时间在运行值。