java基礎之本地線程

java基礎之本地線程

一.概述

    1.1 簡介

            本地線程主要是解決多線程中數據因併發產生不一致的問題。ThreadLocal由一個靜態的class來存放數據,每個對象都在相似map<threadName,value>的數據結構中加入想要的數據。java

    1.2 解釋

            1. Threadlocal:能夠看做一個整個線程變量管理類。這個變量能夠在本線程使用。安全

            2.ThreadLocal是使用一個靜態的 Map<Thead.curentName,Object value> 來存放值. 每次存放都是以線程來存放。因此能夠作到絕對的線程安全數據結構

            3.主要存放 JDBC connection 之類多線程

    1.3. 方法

            1. protected Object initialValue():返回該線程局部變量的初始值,該方法是一個protected的方法,顯然是爲了讓子類覆蓋而設計的。這個方法是一個延遲調用方法,在線程第1次調用get()或set(Object)時才執行,而且僅執行1次。ThreadLocal中的缺省實現直接返回一個null。併發

            2. void set(Object value):設置當前線程的線程局部變量的值。ide

            3. public Object get():該方法返回當前線程所對應的線程局部變量。性能

            4. public void remove():將當前線程局部變量的值刪除,目的是爲了減小內存的佔用,該方法是JDK 5.0新增的方法。須要指出的是,當線程結束後,對應該線程的局部變量將自動被垃圾回收,因此顯式調用該方法清除線程的局部變量並非必須的操做,但它能夠加快內存回收的速度。this

    1.4 組成

          1. threadlocal的源碼spa

        2. 靜態方法賦值
線程

 

    1.5 總結

        1. ThreadLocal使用場合主要解決多線程中數據數據因併發產生不一致問題。ThreadLocal爲每一個線程的中併發訪問的數據提供一個副本,經過訪問副原本運行業務,這樣的結果是耗費了內存,單大大減小了線程同步所帶來性能消耗,也減小了線程併發控制的複雜度。(空間換時間)

        2. ThreadLocal保存的值不能使用原子類型,只能使用Object類型。ThreadLocal的使用比synchronized要簡單得多。 

        3. ThreadLocal和Synchonized都用於解決多線程併發訪問。可是ThreadLocal與synchronized有本質的區別。synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal爲每個線程都提供了變量的副本,使得每一個線程在某一時間訪問到的並非同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用於在多個線程間通訊時可以得到數據共享。 

        4. Synchronized用於線程間的數據共享,而ThreadLocal則用於線程間的數據隔離。 

        5. 固然ThreadLocal並不能替代synchronized,它們處理不一樣的問題域。Synchronized用於實現同步機制,比ThreadLocal更加複雜。 

二.實例

public class MyThreadLocal {

	// 線程本地線程
	public static void main(String[] args) {
		MyThreadLocal mtl = new MyThreadLocal();
		mtl.doMyTest();
	}

	public void doMyTest() {
		ExecutorService es = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++) {
			es.execute(new Test1(i));
		}
		es.shutdown();
	}

}

class Test1 implements Runnable {
	static ThreadLocal<HashMap<Integer, Integer>> maps = new ThreadLocal<HashMap<Integer, Integer>>() {
		protected HashMap<Integer, Integer> initialValue() {
			return new HashMap<Integer, Integer>();
		}
	};
	int id;
	public Test1(int id) {
		this.id = id;
	}
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ": start");
		HashMap<Integer, Integer> map = maps.get();
		for (int i = 0; i < 10; i++) {
			map.put(i, id * 100 + i);
			try {
				Thread.sleep(100);
			} catch (Exception e) {

			}
		}
		System.out.println(Thread.currentThread().getName() + ": " + map);
	}
}

     理解記憶表

相關文章
相關標籤/搜索