Java synchronized 锁字符串注意点
Java 锁 About 5,075 words描述
使用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
Views: 4,190 · Posted: 2020-09-24
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...