1. 程式人生 > >線程學習--(六)單例和多線程、ThreadLocal

線程學習--(六)單例和多線程、ThreadLocal

pen single cal final ride args ash public 線程

一、ThreadLocal

使用wait/notify方式實現的線程安全,性能將受到很大影響。解決方案是用空間換時間,不用鎖也能實現線程安全。

來看一個小例子,在線程內的set、get就是threadLocal

技術分享
package thread2;

public class ConnThreadLocal {

    public static ThreadLocal<String> th = new ThreadLocal<String>();
    
    public void setTh(String value){
        th.set(value);
    }
    
public void getTh(){ System.out.println(Thread.currentThread().getName() + ":" + this.th.get()); } public static void main(String[] args) throws InterruptedException { final ConnThreadLocal ct = new ConnThreadLocal(); Thread t1 = new Thread(new Runnable() { @Override
public void run() { ct.setTh("abc"); ct.getTh(); } }, "t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); ct.getTh(); }
catch (InterruptedException e) { e.printStackTrace(); } } }, "t2"); t1.start(); t2.start(); } }
View Code

技術分享

二、單例和多線程

單例常見的有饑餓模式和懶漢模式,但是這兩個模式在多線程情況下是不行的。在多線程中考慮到新能和線程安全的問題一般考慮double check instance 和 static inner class這兩種方式實現單例模式。

static inner class方式:

package bhz.base.conn011;

public class Singletion {
    
    private static class InnerSingletion {
        private static Singletion single = new Singletion();
    }
    
    public static Singletion getInstance(){
        return InnerSingletion.single;
    }
    
}

double check instance 方式:

技術分享
package thread2;

public class DubbleSingleton {

    private static DubbleSingleton ds;
    
    public  static DubbleSingleton getDs(){
        if(ds == null){
            synchronized (DubbleSingleton.class) {
                if(ds == null){
                    ds = new DubbleSingleton();
                }
            }
        }
        return ds;
    }
    
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t2");
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t3");
        
        t1.start();
        t2.start();
        t3.start();
    }
    
}
View Code

線程學習--(六)單例和多線程、ThreadLocal