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原子变量类模拟多用户多线程访问的主要内容,如果未能解决你的问题,请参考以下文章