對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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章