1. 程式人生 > >資料型別String常量池的特性

資料型別String常量池的特性

package com.test.Thread.StringAndSyn;
/**
 * synchronized(string)同步塊與String聯合使用
 * @author admin
 * 2017年4月20日
 */
public class Service {
    public static void print(String parm) throws InterruptedException{
        synchronized (parm) {
            while(true){
                System.out.println("執行緒名:"
+Thread.currentThread().getName()); Thread.sleep(1000); } } } public static void main(String[] args) { Service s=new Service(); ThreadA a=new ThreadA(s); a.setName("A"); a.start(); ThreadB b=new ThreadB(s); b.setName("B"
); b.start(); } } class ThreadA extends Thread{ private Service s; public ThreadA(Service s) { super(); this.s = s; } @Override public void run() { try { s.print("AAAA"); } catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace(); } } } class ThreadB extends Thread{ private Service s; public ThreadB(Service s) { super(); this.s = s; } @Override public void run() { try { s.print("AAAA"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

執行結果:
這裡寫圖片描述

出現這樣的情況是因為String傳入的兩個值都是AAAA,兩個執行緒只有相同的資源所以造成執行緒B不能執行。這就是String常量池所帶來的問題,因此大多數情況下,同步的synchronized程式碼塊都不使用String作為鎖物件 比如new Object()例項化一個object物件,但它並不放入快取中

修改程式碼如下 會出現交替列印

package com.test.Thread.StringAndSyn;
/**
 * 交替列印的原因是持有鎖不是同一個
 * @author admin
 * 2017年4月20日
 */
public class Service2 {
    public static void print(Object object) throws InterruptedException{
        synchronized (object) {
            while(true){
                System.out.println("執行緒名:"+Thread.currentThread().getName());
                Thread.sleep(1000);
            }
        }
    }

    public static void main(String[] args) {
        Service2 s=new Service2();
        ThreadAA a=new ThreadAA(s);
        a.setName("A");
        a.start();

        ThreadBB b=new ThreadBB(s);
        b.setName("B");
        b.start();

    }
}

class ThreadAA extends Thread{
    private Service2 s;


    public ThreadAA(Service2 s) {
        super();
        this.s = s;
    }


    @Override
    public void run() {
        try {
            s.print("AAAA");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class ThreadBB extends Thread{
    private Service2 s;


    public ThreadBB(Service2 s) {
        super();
        this.s = s;
    }


    @Override
    public void run() {
        try {
            s.print("AAAA");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}