java併發編程基礎——線程相關的類

線程相關類java

java還爲線程安全提供了一些工具類。數據庫

1、ThreadLocal類(Thread Local Variable)小程序

ThreadLocal類,是線程局部變量的意思。功用很是簡單,就是爲每個使用該變量的線程提供一個變量值的副本,使沒一個線程均可以獨立的改變本身的副本,而不會和其餘副本衝突。安全

ThreadLocal提供了3個public方法多線程

T get();返回此線程局部變量中當前線程副本中的值併發

void remove():刪除此線程局部變量中當前線程的值ide

void set(T value):設置此線程局部變量中當前線程副本中的值高併發

ThreadLocal也是爲了解決多線程中對同一變量訪問的衝突。普通的同步機制中是經過對象加鎖來實現對同一變量的安全訪問。工具

ThreadLocal從另外一角度來解決多線程的併發,它是將須要併發訪問的資源複製成多份,每一個線程擁有一份資源,不必對該變量進行同步了。this

ThreadLocal並不能代替同步機制,二者的問題領域不一樣,同步機制是爲了同步多個線程對相同的資源進行併發訪問,是多線程之間進行通訊的有效方式。ThreadLocal是爲了隔離多個線程的數據共享,從根本上避免多個線程之間對共享資源的競爭。

最多見的ThreadLocal使用場景爲 用來解決 數據庫鏈接、Session管理等。

下面小程序說明了ThreadLocal能達到在每一個線程中建立變量副本的效果:

package threadtest; public class ThreadTest implements Runnable{ private ThreadLocal<Integer> i =new ThreadLocal<>(); public int getI() { return i.get(); } public void setI(int i) { this.i.set(i); } @Override public void run() { for(i.set(0);i.get()<100;i.set(i.get()+1)) { System.out.println(Thread.currentThread().getName() + "--------->" + i.get()); } } public static void main(String[] args) { //兩個線程,各自打印各自的值
        ThreadTest tt = new ThreadTest(); Thread t1 = new Thread(tt,"t1"); Thread t2 = new Thread(tt,"t2"); t1.start(); t2.start(); } }

結果:i變量兩個線程各自不影響

t1--------->0 t2--------->0 t1--------->1 t2--------->1 t1--------->2 t2--------->2 t1--------->3 t2--------->3 ... t2--------->94 t2--------->95 t2--------->96 t2--------->97 t2--------->98 t2--------->99 t1--------->15 t1--------->16 t1--------->17 t1--------->18 ... t1--------->97 t1--------->98 t1--------->99

2、包裝線程不安全的集合

Java集合中ArrayList,LinkedList,HashSet,TreeSet,HashMap,TreeMap等都是線程不安全的,就是多個線程併發向這些集合中存取數據,可能會破壞數據的完整性。

若是要多線程訪問這些集合,就須要包裝下,須要用到Collections提供的靜態方法把這些集合包裝成安全的集合,方法以下:

static <T> Collection<T> synchronizedCollection(Collection<T> c)

static <T> List<T> synchronizedList(List<T> list)

static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)

static <T> Set<T> synchronizedSet(Set<T> s)

static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)

static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)

//將ArrayList包裝成安全的
List<String> l =Collections.synchronizedList(new ArrayList<String>());

3、線程安全的集合類

Java5開始,java.util.concurrent包下提供了大量支持高併發訪問的集合接口和實現類

主要分爲兩類:

以Concurrent開頭的集合類,如:ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,ConcurrentLinkedQueue,ConcurrentLinkedDeque

以CopyOnWrite開頭的集合類,如: CopyOnWriteArrayList,CopyOnWriteArraySet.

其中Concurrent開頭的集合類表明了併發訪問的集合,支持多線程併發寫入訪問,這些寫入程序的全部操做都是線程安全的,但讀取不會鎖定。

當多個線程共享訪問一個公共集合時,ConcurrentLinkedQueue是一個不錯的選擇。ConcurrentLinkedQueue實現了多線程的高效訪問,個線程訪問時無需等待

在默認狀況下ConcurrentHashMap支持16個線程併發寫入,超過16個時,可能有些線程須要等待。

相關文章
相關標籤/搜索