在某些业务条件下,对某个并发操作做更细粒度的控制。例如相同的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关键字