1.18 建议用String常量作为锁定对象吗?
2019-03-16 本文已影响0人
殊胜因缘_Chris
/**
* This is description.
* Q: 建议用String常量作为锁定对象吗?
* S: 不建议.
* 不要以字符串常量作为锁定对象
* 在下面的例子中, fun1和fun2其实锁定的是同一个对象
* 这种情况还会发生比较诡异的现象, 比如你用到了一个类库, 在该类库中代码锁定了字符串“Hello”,
* 但是你读不到源码, 所以你在自己的代码中也锁定了"Hello", 这时候就有可能发生非常诡异的死锁阻塞,
* 因为你的程序和你用到的类库不经意间使用了同一把锁.(Jetty框架)
*
* @author Chris Lee
* @date 2019/3/13 22:56
*/
public class Demo {
static String s1 = "name";
static String s2 = "name";
public void fun1() {
synchronized (s1) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
}
}
}
public void fun2() {
// s1 == s2造成死锁, t2线程不打印.
synchronized (s2) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName());
// s1 != this, 此时不会造成死锁, t2线程打印.
/*
synchronized (this) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName());
*/
}
public static void main(String[] args) {
System.out.println("s1 == s2: " + (s1 == s2));
Demo demo = new Demo();
new Thread(demo::fun1, "t1").start();
new Thread(demo::fun2, "t2").start();
}
}
说明:
- 本篇文章如有不正确或待改进的地方, 欢迎批评和指正, 大家一同进步, 谢谢!
- 世上有4样东西可以让世界变得更美好, 它们是: 代码(Code), 诗(Poem), 音乐(Music), 爱(Love). 如有兴趣了解更多, 欢迎光顾"我的文集"相关文章.