对String在多线程中的一些简单认识

  最近在看多线程,synchronized代码块时候说到用String对象来当作锁,然后说最好不要用String对象来当作锁,这是为什么了?可以先看一段程序。

public class StringLock {

    public void method() {
        //new String("字符串常量")
        synchronized ("字符串常量") {
            try {
                while(true){
                    System.out.println("当前线程 : "  +    Thread.currentThread().getName() + "开始");
                    Thread.sleep(1000);     
                    System.out.println("当前线程 : "  + Thread.currentThread().getName() + "结束");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        final StringLock stringLock = new StringLock();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                stringLock.method();
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                stringLock.method();
            }
        },"t2");

        t1.start();
        t2.start();
    }
}

程序运行的结果(部分)是:
  当前线程 : t1开始
  当前线程 : t1结束
不断输出这两句话,这是为什么了?因为锁"字符串常量"是一个常量锁,当你将锁"字符串常量"改成new String("字符串常量"),控制台会输出什么了,t2线程也可以开始运行了。程序运行的结果(部分)是:
  当前线程 : t1开始
  当前线程 : t2开始
  当前线程 : t2结束
  当前线程 : t1结束
这是因为new String("字符串常量")创建的是不同的对象,所以锁不同,两个线程都能执行。这让我想起了我们刚学java的时候有一些书本上会讲到这个列子:

public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = "hello";

        System.out.println(s1 == s2);// false
        System.out.println(s1.equals(s2));// true
    }

  new String("hello")"hello"是两个不同的对象,一个是保存在常量池中,一个是保存在堆中。有些时候业务上就是需要传入一个new String的对象锁了,可以将锁改成new String("字符串常量").intern(),这个锁的本质其实和"字符串常量"这个锁是一样的。
  看看jdk的文档说的:一个初始为空的字符串池,它由类 String 私有地维护。 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
  对于String对象锁在业务上的例子可以参考这篇博文https://www.cnblogs.com/xrq730/p/6662232.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值