博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用synchronized小坑
阅读量:3722 次
发布时间:2019-05-22

本文共 1242 字,大约阅读时间需要 4 分钟。

一般使用synchronized的时候,主要是用在方法上,代码块上,当使用在代码块的时候一般锁的都是类或者对象,但是有的人会去锁封装的常量。这个时候去锁这个封装的常量就会有问题了,我们来写个简单的demo来看看什么问题。

错误使用案例:

public static void print(Integer num) {
synchronized (num) {
try {
Thread.sleep(1000); } catch (InterruptedException e) {
e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis() / 1000);    }}

当num为2的时候输出

没有问题对吧。

把num换成128输出:

这时候就有问题了都是单独运行的统一时间执行的,测试完后就会发现-128~127

范围的数字是锁住了,但是这个范围之外的没有锁住,是什么原因呢?下面就为你揭晓答案哦:

debug  Integer num = 129;在valueOf上打断点后看到

初始化就会调用valueOf,如果在-128~127就会存缓存里面取,不在这个范围就会new 一个对象放进去,new 对象地址都不一样肯定是锁不住了呀。Long类型也是一样的

那如果你要锁一个常量怎么办呢?

可以转换为String锁字符串,前面加一个单独的标识拼接一下。错误的使用:

public static void print(Integer num) {
String key = "NUM_KEY_" + num; synchronized (key) {
try {
Thread.sleep(1000); } catch (InterruptedException e) {
e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis() / 1000); }}

这样的你觉得可以锁住不?答案肯定锁不住的因为String拼接时候就是

new String的操作这样拼接后地址不一样了,导致锁不住。

一定要用常量的话,可以写成静态的,或者使用分布式锁等,

尽量避免锁这样的数字吧。还有就是Double,Float小数是一个都锁不住的哦。

 

                                         文章同时会更新到公众号,觉得对你有帮助或者有用的可以关注一下哦 

转载地址:http://cgfnn.baihongyu.com/

你可能感兴趣的文章
刷题笔记(19)--把数组排成最小的数
查看>>
刷题笔记(20)--对称的二叉树
查看>>
js实现输入框的验证
查看>>
反转链表II
查看>>
排序链表
查看>>
对链表进行插入排序
查看>>
回文链表
查看>>
逆波兰表达式求值
查看>>
字符串解码
查看>>
若依管理系统部署到IDEA
查看>>
超详细的KMP算法
查看>>
贪心入门之——埃及分数问题
查看>>
Xilinx_ISE14.7安装包网盘下载
查看>>
MyBatis知识点复习-11一级缓存与二级缓存以及ehcache缓存
查看>>
贪心之徒(图)
查看>>
组合贪心
查看>>
算法——四处碰壁回溯法02图解回溯
查看>>
MyBatis知识点复习-13Mybatis注解开发
查看>>
MyBatis知识点复习-0前言目录
查看>>
Java基础复习——注解详细介绍
查看>>