Java原子变量类模拟多用户多线程访问

Posted 结构化思维wz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java原子变量类模拟多用户多线程访问相关的知识,希望对你有一定的参考价值。

原子变量类

原子变量类基于CAS实现的,当对共享变量进行 read-modify-writer更新操作时,通过原子变量类可以保障操作的原子性与可见性,对变量的read-modify-writer更新操作是指当前操作不是一个简单的赋值,而是一个变量的新值依赖变量的旧值。

例如 i++ 的操作就是 读 -> +1 -> 赋值;

由于volatile无法保证原子性,只能保证可见性,原子变量类内部就是借助一个volatile变量,并且保障了该变量的 read-modify-writer 操作的原子性,有时把原子变量类看做增强的 volatile变量。

原子变量类:

分组原子变量类
基础数据类型AtomicInteger,AtomicLong,AtomicBoolean
数组型AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
字段更新器AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater
引用型AtomicReference,AtomicStampedReference,AtomicMarkableReference

使用AtomicLong定义计数器

开发一个程序统计请求的总数,成功数,失败数。模拟多用户多线程访问。

package se.high.thread.atomic.atomiclong;

import java.util.concurrent.atomic.AtomicLong;

/**
 * @author 结构化思维wz
 * 使用原子变量类定义一个计数器
 * 统计计数器,在整个程序中都能使用,并且所有地方都使用这一计数器,这个计数器可以设计为单例
 */

public class Indicator {
    //构造方法私有化
    private Indicator(){}
    //定义一个私有的本类静态对象
    private static final Indicator INSTANCE = new Indicator();
    //提供一个公共静态方法返回该类的唯一实例
    public static Indicator getInstance(){
        return INSTANCE;
    }
    /**
     * 记录原子变量类保存请求总数,成功数,失败数。
     */
    private final AtomicLong requestCount = new AtomicLong(0); //记录请求总数
    private final AtomicLong successCount = new AtomicLong(0); //记录请求成功数
    private final AtomicLong fialureCount = new AtomicLong(0); //记录请求失败数

    /**
     * 有新的请求的时候
     */
    public void newRequestReceive(){
        requestCount.incrementAndGet(); //总数增长
    }
    /**
     * 处理成功的时候
     */
    public void requestSuccess(){
        successCount.incrementAndGet(); //成功数+1
    }
    /**
     * 处理失败的时候
     */
    public void requestFialure(){
        fialureCount.incrementAndGet(); //失败数+1
    }

    /**
     * 查看总数,成功数,失败数
     */
    public long getRequestCount(){
        return requestCount.get();
    }
    public long getRequestSuccess(){
        return successCount.get();
    }
    public long getRequestFialure(){
        return fialureCount.get();
    }
}

package se.high.thread.atomic.atomiclong;

import java.util.Random;

/**
 * @author 结构化思维wz
 * 模拟服务器的请求总数,处理成功数,处理失败数。
 */

public class AtomicTest {
    public static void main(String[] args) {
        // 通过线程模拟请求
        for (int i = 0; i < 10000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //每个线程都是一个请求
                    Indicator.getInstance().newRequestReceive();
                    int num = new Random().nextInt();
                    if (num %2 == 0){
                        //偶数模拟成功
                        Indicator.getInstance().requestSuccess();
                    }else {Indicator.getInstance().requestFialure();}
                }
            }).start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //打印结果
        System.out.println("请求的总数--->"+Indicator.getInstance().getRequestCount());
        System.out.println("请求成功数--->"+Indicator.getInstance().getRequestSuccess());
        System.out.println("请求失败数--->"+Indicator.getInstance().getRequestFialure());

    }

}

请求的总数--->10000
请求成功数--->5035
请求失败数--->4965

进程已结束,退出代码为 0

以上是关于Java原子变量类模拟多用户多线程访问的主要内容,如果未能解决你的问题,请参考以下文章

java多线程笔记--Atomic原子操作类

JAVA多线程学习九-原子性操作类的应用

Java多线程安全原子性之AtomicCASSynchronized和Lock

多线程与并发Java中的12个原子操作类

Java——多线程高并发系列之理解CAS原子变量类的使用

Java——多线程高并发系列之理解CAS原子变量类的使用