在某些业务条件下,对某个并发操作做更细粒度的控制。例如相同的id(字符串),并发操作才是不被允许的,此时可以使用String的intern方法返回的对象做锁。而不是不分青红皂白直接全部加锁,那么整体性能就下降得厉害了。
代码如下:

public class Test {
    public void fun(String str) {
        synchronized (str.intern()) {
            System.out.println("线程名:" + Thread.currentThread().getName() + ",同步方法,运行开始");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程名:" + Thread.currentThread().getName() + ",同步方法,运行结束");
        }
    }
    public static void main(String[] args) {
        Test test1 = new Test();
        Test test2 = new Test();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test1.fun("10001");
            }
        },"线程1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test2.fun("10001");
            }
        },"线程2").start();
    }
}

运行结果:

线程名:线程1,同步方法,运行开始
线程名:线程1,同步方法,运行结束
线程名:线程2,同步方法,运行开始
线程名:线程2,同步方法,运行结束

当线程2的id改为10002时,运行结果:

线程名:线程1,同步方法,运行开始
线程名:线程2,同步方法,运行开始
线程名:线程2,同步方法,运行结束
线程名:线程1,同步方法,运行结束

由此可见,不同线程使用不同对象的方法的时候,的确实现了基于字符串的同步锁。

事实上,intern方法会去字符串池中获取对应的对象,相同字符串获取到的对象一定是同一个,所以结合同步块才能实现基于字符串的同步锁。

相关资料:intern关键字


标题:基于字符串实现同步锁
作者:xingzhegu
地址:https://www.fxg.life/articles/2021/12/29/1640782939127.html