ThreadLocal与Synchronized的用法
生活随笔
收集整理的這篇文章主要介紹了
ThreadLocal与Synchronized的用法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
來源:http://blog.csdn.net/wl_ldy/article/details/5948779
一.ThreadLocal的用法
ThreadLocal的實現:
Synchronized的實現:
ThreadLocal使用場合主要解決多線程中數據數據因并發產生不一致問題。 ThreadLocal為每個線程的中并發訪問的數據提供一個副本 ,通過訪問副本來運行業務,這樣的結果是耗費了內存,單大大減少了線程同步所帶來性能消耗,也減少了線程并發控制的復雜度。?
ThreadLocal不能使用原子類型,只能使用Object類型。ThreadLocal的使用比synchronized要簡單得多。?
ThreadLocal和Synchonized都用于解決多線程并發訪問。但是ThreadLocal與synchronized有本質的區別。 synchronized是利用鎖的機制,使變量或代碼塊在某一時刻只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數據的數據共享。 而Synchronized卻正好相反,它用于在多個線程間通信時能夠獲得數據共享。?
Synchronized用于線程間的數據共享,而ThreadLocal則用于線程間的數據隔離。 ?
當然ThreadLocal并不能替代synchronized,它們處理不同的問題域。Synchronized用于實現同步機制,比ThreadLocal更加復雜。?
ThreadLocal使用的一般步驟:?
1、在多線程的類(如ThreadDemo類)中,創建一個ThreadLocal對象threadXxx,用來保存線程間需要隔離處理的對象xxx。?
2、在ThreadDemo類中,創建一個獲取要隔離訪問的數據的方法getXxx(),在方法中判斷,若ThreadLocal對象為null時候,應該new()一個隔離訪問類型的對象,并強制轉換為要應用的類型。?
3、在ThreadDemo類的run()方法中,通過getXxx()方法獲取要操作的數據,這樣可以保證每個線程對應一個數據對象,在任何時刻都操作的是這個對象。
二.ThreadLocal的實現原理:
public class ThreadLocal { private Map values = Collections.synchronizedMap(new HashMap()); public Object get() { Thread curThread = Thread.currentThread(); Object o = values.get(curThread); if (o == null && !values.containsKey(curThread)) { o = initialValue(); values.put(curThread, o); } return o; } public void set(Object newValue) { values.put(Thread.currentThread(), newValue); } public Object initialValue() { return null; } } 由此可見,ThreadLocal通過一個Map來為每個線程都持有一個變量副本。這個map以當前線程為key。與synchronized相比,ThreadLocal是以空間換時間的策略來實現多線程程序。?
Synchronized還是ThreadLocal??
ThreadLocal以空間換取時間,提供了一種非常簡便的多線程實現方式。因為多個線程并發訪問無需進行等待,所以使用ThreadLocal會獲得更大的性能。雖然使用ThreadLocal會帶來更多的內存開銷,但這點開銷是微不足道的。因為保存在ThreadLocal中的對象,通常都是比較小的對象。另外使用ThreadLocal不能使用原子類型,只能使用Object類型。ThreadLocal的使用比synchronized要簡單得多。?
ThreadLocal和Synchonized都用于解決多線程并發訪問。但是ThreadLocal與synchronized有本質的區別。synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用于在多個線程間通信時能夠獲得數據共享。?
Synchronized用于線程間的數據共享,而ThreadLocal則用于線程間的數據隔離。?
當然ThreadLocal并不能替代synchronized,它們處理不同的問題域。Synchronized用于實現同步機制,比ThreadLocal更加復雜。
2012-05-23新增 每一個線程都維護一個本地對象的副本,類圖如:
ThreadLocal 只是提供當前線程(Thread.currentThread( ) )對副本(ThreadLocal.ThreadLocalMap)的操作。 部分源代碼 public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null)return (T)e.value;}return setInitialValue();} ThreadLocalMap getMap(Thread t) {return t.threadLocals;}
疑問:ThreadLocal每種類型的對象只能存儲一個? 應該是的,因為 map 的key 值是 ThreadLocal對象。下面是 ThreadLocal 部分源代碼: public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}
總結
以上是生活随笔為你收集整理的ThreadLocal与Synchronized的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Guava入门~Charsets
- 下一篇: 代码精进之路--思维导图