简体   繁体   English

并发线程安全AtomicInteger

[英]Concurrent Thread-safe AtomicInteger

I've read through the API documentation of the java.util.concurrent package, but have obviously misunderstood something. 我已经阅读了java.util.concurrent包的API文档,但显然有误解。 The overview says 概述说

A small toolkit of classes that support lock-free thread-safe programming on single variables. 一个小的类工具包,支持对单个变量进行无锁线程安全编程。

However, a small test application shows that the AtomicInteger class does not provide thread-safety, at least when it is shared across threads (I accept that the getAndSet / increment methods themselves are at least atomic ) 但是,一个小型测试应用程序显示AtomicInteger类至少在跨线程共享时不提供线程安全性(我接受getAndSet / increment方法本身至少是原子的 )。

Test: 测试:

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();
                }
            }
        }
    }
}

When I run this class, I consistently get results ranging from around 950 to 1000, when I would expect to always see exactly 1000. 当我上这节课时,我总是得到大约950到1000的结果,而我希望总是能看到1000。

Can you explain why do I not get consistent results when two threads access this shared AtomicInteger variable? 您能解释一下为什么两个线程访问此共享的AtomicInteger变量时无法获得一致的结果吗? Have I misunderstood the thread-safety guarantee? 我是否误解了线程安全保证?

Looks like a simple cut&paste error - you are joining to thread "w2" twice and never to "w1". 看起来像一个简单的剪切和粘贴错误-您将两次加入线程“ w2”,而从未加入“ w1”。 At present, you would expect the thread "w1" to still be running half the time when you print the 'final' value. 目前,您希望线程“ w1”在打印“最终”值时仍在运行一半时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM