2.2.10數據類型String的常量池特性

/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {
    public static void print(String stringParam){
        try{
            synchronized (stringParam) {
                while (true) {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
       super.run();
        service.print("AA");
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

   private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.print("AA");
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      Service service=new Service();
      ThreadA a=new ThreadA(service);
      a.setName("A");
      a.start();
      ThreadB b=new ThreadB(service);
      b.setName("B");
      b.start();
    }
}

程序的運行結果為:

A
A
A
A

出現這樣的情況就是因為String的兩個值都是AA,兩個線程持有相同的鎖,所以造成線程B不能執行。這就是String常量池所帶來的問題。因此在大多數情況下,同步synchronized代碼塊都不使用String作為鎖對象,而改用其他,比如new Object()實例化一個Object對象,但它并不放入緩存中。

/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {
    public static void print(Object object){
        try{
            synchronized (object) {
                while (true) {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
       super.run();
        service.print(new Object());
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

   private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.print(new Object());
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
      Service service=new Service();
      ThreadA a=new ThreadA(service);
      a.setName("A");
      a.start();
      ThreadB b=new ThreadB(service);
      b.setName("B");
      b.start();
    }
}

程序的運行結果為:

A
B
A
B
B
A
B
A
B
A

交替打印的原因是持有的鎖不是一個。

摘選自 java多線程核心編程技術-2.2.10

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容