美文网首页多线程与并发
1.18 建议用String常量作为锁定对象吗?

1.18 建议用String常量作为锁定对象吗?

作者: 殊胜因缘_Chris | 来源:发表于2019-03-16 11:40 被阅读0次
    /**
     * 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). 如有兴趣了解更多, 欢迎光顾"我的文集"相关文章.
    资料:
    1. 学习视频: https://www.bilibili.com/video/av11076511/?p=1
    2. 参考代码: https://github.com/EduMoral/edu/tree/master/concurrent/src/yxxy
    3. 我的代码: https://github.com/ChrisLeejing/learn_concurrency.git

    相关文章

      网友评论

        本文标题:1.18 建议用String常量作为锁定对象吗?

        本文链接:https://www.haomeiwen.com/subject/dowjmqtx.html