1. 程式人生 > >ThreadLocal和單例對象比較

ThreadLocal和單例對象比較

自動 map let 資源 private static println 獨立 get

單例對象: 自始至終只有一個對象

當線程並發,每個線程需要自己獨立的資源變量處理不同的業務時,單例對象遠遠不能滿足需求

因此可以采用ThreadLocal模式 : 每個線程有自己獨立的資源變量 而且每個線程的資源是獨享的 其他線程不能訪問和修改

筆者剛開始工作時候使用的Struts2,也曾略讀過Struts2源碼;就個人而言 雖然和現在對比已經過時,但是Struts2的設計思想還是很不錯的,每個請求對應一個Action對象

也是ThreadLocal的代表,除去Struts2的標簽和OGNL,整體性能也是不錯的,讀者有興趣可以自己研究一下

單利模式:

//單例模式 私有構造  只有一個對象
public class Singleton{ private static Singleton instance = null; private Singleton(){} public synchronized static Singleton getInstance(){ if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance
= new Singleton(); } } } return instance; } }

ThreadLocal模式

  

public class Struts2{
    
    private static ThreadLocal<Struts2> map = new ThreadLocal<Struts2>();
    
    private Struts2(){
        
    }
    
    // synchronized不需要設置    每個線程享有自己獨立資源
public static Struts2 getThreadInstance(){ Struts2 instance = map.get(); if(instance == null){ instance = new Struts2(); map.set(instance); } return instance; } //Strtus2就是這種設計思想 private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }

//測試類
public
class TestThreadLocal{ public static void main(String[] args) { for(int i=0;i<2;i++){ new Thread(new Runnable(){ @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data :" + data); Struts2.getThreadInstance().setMsg(data+""); //存數據 new UserA().get(); new UserB().get(); } }).start(); } } static class UserA{ public void get(){ Struts2 obj = Struts2.getThreadInstance(); System.out.println("UserB from " + Thread.currentThread().getName() + " 數據是 : "+obj.getMsg() ); } } static class UserB{ public void get(){ Struts2 obj = Struts2.getThreadInstance(); System.out.println("UserB from " + Thread.currentThread().getName() + " 數據是 : "+obj.getMsg() ); } } }


輸出結果:

Thread-1 has put data :223586296
Thread-0 has put data :1184404572
UserB from Thread-0 數據是 : 1184404572
UserB from Thread-1 數據是 : 223586296
UserB from Thread-1 數據是 : 223586296
UserB from Thread-0 數據是 : 1184404572

 

備註:每個線程有只屬於這個線程的對象,每個線程享有自己獨立的副本,內部相當於一個Map key[當前線程] - vlaue[值], 線程結束後 會自動把結束的線程移除,不需要自己remove

ThreadLocal和單例對象比較