java - 并发线程安全 AtomicInteger

标签 java multithreading concurrency atomicinteger

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

A small toolkit of classes that support lock-free thread-safe programming on single variables.

但是,一个小型测试应用程序表明 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();
                }
            }
        }
    }
}

当我运行这个类(class)时,我始终得到大约 950 到 1000 之间的结果,而我期望总是看到正好 1000。

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

最佳答案

看起来像一个简单的剪切和粘贴错误 - 您两次加入线程“w2”,但从未加入“w1”。目前,当您打印“最终”值时,您会期望线程“w1”仍在运行一半的时间。

关于java - 并发线程安全 AtomicInteger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29166168/

相关文章:

concurrency - 我们什么时候应该选择锁定而不是无锁数据结构”

java - MyBatis - 在同一服务调用中连接到多个数据库

java - 无法实例化一个或多个类?

java - 为什么Java中Swing GUI关闭后新线程也会退出

java - ThreadFactory 和 newThread(Runnable r) 如果它是线程,如何访问 r 的属性?

java - 使用 hibernate 和线程锁定

objective-c - NSNotificationCenter 线程安全吗?

java - 继承接口(interface)方法的aspectj切入点

java - 在Hadoop上运行Java程序

java - 有什么方法或工具可以用来验证我的 API 在 Java 中是否是线程安全的?