当前位置:网站首页>多线程 里面 使用AtomicInteger类,保证线程安全
多线程 里面 使用AtomicInteger类,保证线程安全
2022-08-03 17:41:00 【一天不写程序难受】
目录
1 什么叫做线程安全
假设我们的网站要统计用户人数,我们需要通过变量的自增来实现:count++; 这个操作存在线程安全问题:
最后统计的人数是少的;
2 问题分析
count++的操作分为三步:
读取count的值
计算count+1的值
把新值存入count
假设count值为100,两个线程A和B都执行了操作1,
再同时执行操作2,A先进行操作3,这时count值为101,
B再执行操作3,之前B读取的值是100,执行完操作3后B
的结果还是101,这样数据出现了问题。因为上面的操作
不是原子的,可以分开执行。
3 解决
AtomicInteger出现解决了上面的问题,使用它来执行统计:
static AtomicInteger at = new AtomicInteger(0);
public static void main(String[] args) {
for(int i = 0;i < 10000;i++){
new Thread(()->{at.incrementAndGet();}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("count = " + at.get());
}
AtomicInteger 源码里面有关键字volatile; 它确保对volatile字段的更新以可预见的方式告知其他的线程。简而言之volatile 的作用是当一个线程修改了变量时,另一个线程可以读取到这个修改后的值。
4 总结
AtomicInteger能够实现整型数据的原子操作,在多线程并发的环境下能保证数据安全,而且内部使用乐观锁实现,比使用锁机制的并发性能高;
volatile保证了一个线程修改数据时,其它线程也能看到数据的修改 CAS操作保证了数据修改的安全性
5 线程统计失败个数
多个线程执行一段逻辑,统计有多少个线程失败了
ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>();
//分10个线程,每个线程自增2000次
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 2000; i++) {
AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(22, new AtomicInteger(1));
if (timeoutCount != null) {
// 记录慢任务慢的次数
timeoutCount.incrementAndGet();
}
}
}
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(jobTimeoutCountMap.get(22));
边栏推荐
猜你喜欢
随机推荐
leetcode-每日一题899. 有序队列(思维题)
Is OnePlus Ace worth buying?Use strength to interpret the power of performance
A complete detailed tutorial on building intranet penetration ngrok (with pictures and truth)
NLP范式新变化:Prompt
【mysql】SIGN(x) function
全尺度表示的上下文非局部对齐,南科大&优图提出NAFS解决基于文本的Re ID
MySQL database account management and optimization
腾讯电竞的蓝翔梦
分享 14 个你必须知道的 JS 函数
云GPU如何安装和启动VNC远程桌面服务?
uniapp 切换 history 路由模
为什么我用了Redis之后,系统的性能却没有提升
华为ECS云服务器上安装Docker及部署Redis详细教程【华为云至简致远】
InnoDB 中不同SQL语句设置的锁
Interpretation of the paper (JKnet) "Representation Learning on Graphs with Jumping Knowledge Networks"
JS 字符串转 GBK 编码超精简实现
【GAMES101】作业6 加速结构
融云「音视频架构实践」技术专场【内含完整PPT】
“vite”和“vite预览”有什么区别?
【指针初解】