美文网首页多线程与并发
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常量作为锁定对象吗?

    说明: 本篇文章如有不正确或待改进的地方, 欢迎批评和指正, 大家一同进步, 谢谢! 世上有4样东西可以让世界变得...

  • 使用String对象当锁的弊端

    String对象存在于常量池中,相同内容的String对象地址相同,为同一对象。因此如果使用String作为锁时,...

  • String.intern

    • 直接使用双引号声明出来的String对象会直接存储在常量池中。• 如果不是用双引号声明的String对象,可以...

  • vba

    定义常量 整个工程用public,整个模块用private 变量 数据类型如string,interger等,对象...

  • 字符串

    String类 在java中,字符串被作为String类型的对象处理,即String是字符串常量的类。 创建Str...

  • java——String类

    String类的特点: String是常量创建的对象不能改变如果改变就创建新的对象首先检查常量池中是否有该字符串,...

  • String 类和常量池

    String 类和常量池 String 对象的两种创建方式: String str1 = "abcd";//先检查...

  • java学习笔记-String,StringBuffer,Str

    都是对象,引用类型。 String:字符串常量,存在于常量池,字符串长度不可变。Java 中 String 是 i...

  • 关于java String的“==”和equals()比较、引用

    String s1 = "String"; 这种方式,java首先会在缓冲区查找是否有"String"这个常量对象...

  • Java内存模型

    常量池1.使用String并不一定创建对象String s1 = "abc"; // 常量池中没有,则创建"ab...

网友评论

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

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