java synchronized 递归_Java synchronized锁字符串注意点

描述

使用synchronized关键字,根据不同字符串进行上锁。

public static void main(String[] args) {

for (int i = 0; i < 10; i++) {

String lock = String.valueOf(i % 2);

int finalI = i;

new Thread(() -> {

synchronized (lock) {

System.out.println(LocalDateTime.now() + ", lock Current value#" + finalI + ", Current lock#" + lock + ", Current Thread#" + Thread.currentThread().getId());

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(LocalDateTime.now() + ", unlock Current value#" + finalI + ", Current lock#" + lock + ", Current Thread#" + Thread.currentThread().getId());

}

}).start();

}

}

日志输出

2020-08-21T10:14:57.410, lock Current value#1, Current lock#1, Current Thread#13

2020-08-21T10:14:57.410, lock Current value#5, Current lock#1, Current Thread#17

2020-08-21T10:14:57.410, lock Current value#2, Current lock#0, Current Thread#14

2020-08-21T10:14:57.409, lock Current value#6, Current lock#0, Current Thread#18

2020-08-21T10:14:57.409, lock Current value#0, Current lock#0, Current Thread#12

2020-08-21T10:14:57.410, lock Current value#9, Current lock#1, Current Thread#21

2020-08-21T10:14:57.409, lock Current value#4, Current lock#0, Current Thread#16

2020-08-21T10:14:57.409, lock Current value#3, Current lock#1, Current Thread#15

2020-08-21T10:14:57.410, lock Current value#8, Current lock#0, Current Thread#20

2020-08-21T10:14:57.409, lock Current value#7, Current lock#1, Current Thread#19

2020-08-21T10:15:02.410, unlock Current value#0, Current lock#0, Current Thread#12

2020-08-21T10:15:02.410, unlock Current value#4, Current lock#0, Current Thread#16

2020-08-21T10:15:02.410, unlock Current value#5, Current lock#1, Current Thread#17

2020-08-21T10:15:02.410, unlock Current value#9, Current lock#1, Current Thread#21

2020-08-21T10:15:02.410, unlock Current value#6, Current lock#0, Current Thread#18

2020-08-21T10:15:02.410, unlock Current value#2, Current lock#0, Current Thread#14

2020-08-21T10:15:02.411, unlock Current value#3, Current lock#1, Current Thread#15

2020-08-21T10:15:02.410, unlock Current value#1, Current lock#1, Current Thread#13

2020-08-21T10:15:02.411, unlock Current value#7, Current lock#1, Current Thread#19

2020-08-21T10:15:02.411, unlock Current value#8, Current lock#0, Current Thread#20

原因

使用字符串锁,但每次都是new了一个新对象,所以起不了锁的效果。而如果测试synchronized ("1")锁固定常量字符串则锁有效。

原因是:new的对象在堆上分配,每次都不同。

解决方法

使用String的intern()方法,将堆上的String写入常量池中。常量池中如果有数据,则直接取常量池中数据;常量池中如果没有数据,则将数据写入常量池并返回常量池中的数据。

public static void main(String[] args) {

for (int i = 0; i < 10; i++) {

String lock = String.valueOf(i % 2);

int finalI = i;

new Thread(() -> {

synchronized (lock.intern()) {

System.out.println(LocalDateTime.now() + ", lock Current value#" + finalI + ", Current lock#" + lock + ", Current Thread#" + Thread.currentThread().getId());

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(LocalDateTime.now() + ", unlock Current value#" + finalI + ", Current lock#" + lock + ", Current Thread#" + Thread.currentThread().getId());

}

}).start();

}

}

日志输出

2020-08-21T10:14:00.774, lock Current value#1, Current lock#1, Current Thread#13

2020-08-21T10:14:00.774, lock Current value#0, Current lock#0, Current Thread#12

2020-08-21T10:14:05.775, unlock Current value#1, Current lock#1, Current Thread#13

2020-08-21T10:14:05.775, unlock Current value#0, Current lock#0, Current Thread#12

2020-08-21T10:14:05.775, lock Current value#5, Current lock#1, Current Thread#17

2020-08-21T10:14:05.775, lock Current value#8, Current lock#0, Current Thread#20

2020-08-21T10:14:10.776, unlock Current value#5, Current lock#1, Current Thread#17

2020-08-21T10:14:10.776, unlock Current value#8, Current lock#0, Current Thread#20

2020-08-21T10:14:10.776, lock Current value#9, Current lock#1, Current Thread#21

2020-08-21T10:14:10.776, lock Current value#4, Current lock#0, Current Thread#16

2020-08-21T10:14:15.776, unlock Current value#9, Current lock#1, Current Thread#21

2020-08-21T10:14:15.776, unlock Current value#4, Current lock#0, Current Thread#16

2020-08-21T10:14:15.776, lock Current value#7, Current lock#1, Current Thread#19

2020-08-21T10:14:15.776, lock Current value#6, Current lock#0, Current Thread#18

2020-08-21T10:14:20.777, unlock Current value#6, Current lock#0, Current Thread#18

2020-08-21T10:14:20.777, unlock Current value#7, Current lock#1, Current Thread#19

2020-08-21T10:14:20.777, lock Current value#2, Current lock#0, Current Thread#14

2020-08-21T10:14:20.777, lock Current value#3, Current lock#1, Current Thread#15

2020-08-21T10:14:25.778, unlock Current value#2, Current lock#0, Current Thread#14

2020-08-21T10:14:25.778, unlock Current value#3, Current lock#1, Current Thread#15

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值