当前位置: 首页 > news >正文

加锁常见的问题

锁其是用来控制在某些场景下让代码串行的工具。我们为了充分利用计算机的硬件性能,发明了多线程,多线程有好处,但同时也有它复杂的一面,必须控制好多个线程的执行,才能驯服这个有能力也有脾气的烈马。

一、加锁范围误区

下面add()方法加了锁的,但是compare()方法中还是会出现a != b的场景。必须要考虑锁的范围。add()方法加了同步,只会保证多个线程在执行add()方法是串行的,也即保证a和b一起递增。但是compare()方法并不和add()方法串行,所以,当add()方法执行到一半时,是有可能执行compare()方法,也就是出现a大于b的情况。

@Slf4j
public class Test {public static void main(String[] args) {Test test = new Test();new Thread(()->test.add()).start();new Thread(()->test.compare()).start();}volatile int a = 1;volatile int b = 1;public synchronized void add() {log.info("add start");for (int i = 0; i < 10000; i++) {a++;b++;}log.info("add done");}public void compare() {log.info("compare start");for (int i = 0; i < 10000; i++) {if (a != b) {log.info("a:{},b:{},{}", a, b, a > b);}}log.info("compare done");}}

 执行结果:

二、 锁级别的误判

要让多个线程串行执行,宗旨就是让他们去争同一个东西,我们姑且把这个东西称为锁。在JAVA中,锁可以为类级别和实例级别。

下面代码中,add()方法就是实例级别的锁,导致多线程下不同实例并不会串行,但是coun又是多线程共享的,导致,自增操作被破坏,无法达到预期的值。
 

@Slf4j
public class Test {private static int count;public static void main(String[] args) {IntStream.rangeClosed(1, 1000).parallel().forEach(i -> new Test().add());log.info("count={}", Test.count);}public synchronized void add() {count++;}
}

执行结果:

 

http://www.lryc.cn/news/183797.html

相关文章:

  • 【LeetCode力扣】LCR170 使用归并排序的思想解决逆序对问题(详细图解)
  • python经典百题之一个素数能被几个9整除
  • Thymeleaf 内联语法使用教程
  • Django学习笔记-实现聊天系统
  • C++转换函数
  • Spring Boot中的@Controller使用教程
  • 【17】c++设计模式——>原型模式
  • 金三银四好像消失了,IT行业何时复苏!
  • PDF文件超出上传大小?三分钟学会PDF压缩
  • java入坑之国际化编程
  • Kafka客户端核心参数详解
  • 踩大坑ssh免密登录详细讲解
  • 操作系统八股
  • Hudi SQL DDL
  • gin 框架的 JSON Render
  • 《Dataset Condensation with Differentiable Siamese Augmentation》
  • 多普勒频率相关内容介绍
  • win10睡眠快捷方式
  • C++中的static和extern关键字
  • JAVA经典百题之找完数
  • CSS 滚动驱动动画 view-timeline-inset
  • ansible部署二进制k8s
  • Nginx限流熔断
  • QQ登录的具体流程
  • 用JMeter对HTTP接口进行压测(一)压测脚本的书写、调试思路
  • 接着聊聊如何从binlog文件恢复误delete的数据,模拟Oracle的闪回功能
  • 计算机竞赛 深度学习机器视觉车道线识别与检测 -自动驾驶
  • pyqt5使用经验总结
  • 【MQTT】mosquitto库中SSL/TLS相关API接口
  • 假期题目整合