使用String对象当锁的弊端

String对象存在于常量池中,相同内容的String对象地址相同,为同一对象。因此如果使用String作为锁时,如果之前设置String对象锁的值与后面设置的锁对应的String对象值相同则会影响代码的执行,比如下面的例子:

public class TestStringLock {

    String str1 = "abc";
    String str2 = "abc";

    private void m1() {
        print1();
    }

    private void m2() {
        print2();
    }

    private void print1() {
        synchronized (str1) {
            try {
                while (true) {
                    System.out.println("currentThreadName : " + Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }
    private void print2() {
        synchronized (str2) {
            try {
                while (true) {
                    System.out.println("currentThreadName : " + Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        TestStringLock t = new TestStringLock();
        Thread t1 = new Thread(t::m1, "t1");
        Thread t2 = new Thread(t::m2, "t2");
        t1.start();
        t2.start();
    }
}
currentThreadName : t1
currentThreadName : t1
currentThreadName : t1
currentThreadName : t1
currentThreadName : t1
currentThreadName : t1
currentThreadName : t1

上面代码中线程t1一直占用str1这把锁,t2会占用str2这把锁,按照常理两个线程不应该会相互影响,但是由于两个String对象值是一样的,因此t2线程实际是拿不到执行print2()方法的锁,因此会一直打印t1。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。