在Java的線程編寫,大部分能夠用成熟的工具類來實現。java
ThreadLocal<Integer> x = new ThreadLocal<Integer>();
一個線程有一個空間能夠共享。能夠利用泛型設計複雜的數據結構數組
也能夠利用這個設計線程的單例模式數據結構
/** * @author wengwh * @Date 2014-8-4 */ public class MyThreadScopeData { private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>(); private MyThreadScopeData() { }; public static MyThreadScopeData getThreadInstance() { MyThreadScopeData instance = map.get(); if (instance == null) { instance = new MyThreadScopeData(); map.set(instance); } } }
jdk提供了幾種類型的線程池,能夠根據須要選擇其中一種。併發
ExecutorService threadPool = Executors.newFixedThreadPool(3); threadPool.execute(new Runnable() { @Override public void run() { } });
Future取得的結果類型和Callable返回的結果類型必須一致,這是經過泛型來實現的。dom
Callable要採用ExecutorService的submit方法提交,返回的future對象能夠取消任務。ide
CompletionService用於提交一組Callable任務,其task方法返回已完成的一個Callable任務對應的Future對象。工具
Future<String> future = threadPool.submit(new Callable<String>() { public String call() { return "hello"; } }); try { System.out.println(future.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
比較簡單的示例性能
Lock lock = new ReentrantLock(); lock.lock(); try{ for(int i=0;i<10;i++){ System.out.println(i); } }finally{ lock.unlock(); }
讀寫鎖就是一種,能夠同時讀,不能同時讀寫,寫寫ui
代碼示例:線程
ReentrantReadWriteLock writeLock = new ReentrantReadWriteLock(); writeLock.readLock().lock(); writeLock.readLock().unlock(); writeLock.writeLock().lock(); writeLock.readLock().lock(); writeLock.writeLock().unlock(); writeLock.readLock().unlock();
Condition的功能相似在傳統線程技術中的Object.wait和Object.notify的功能
能夠經過定義2個condition對象來實現生產者模式
Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); lock.lock(); condition.await(); condition.signal(); lock.unlock();
Semaphore能夠維護當前訪問自身的線程個數,並提供了同步機制。使用Semaphore能夠控制同時訪問資源的線程個數,例如:實現一個文件容許的併發訪問數。
Semaphore sp = new Semaphore(3); sp.acquire();獲取一個信號 sp.release();釋放一個信號
CyclicBarrier是要等到所有的線程都到達纔會一塊兒進行下去
例子:直接到有3個都到達了纔會繼續下一個
final CyclicBarrier cb = new CyclicBarrier(3); for(int i=0;i<3;i++){ Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep((long)Math.random()*10000); System.out.println(cb.getNumberWaiting()); cb.await(); System.out.println("end"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; Thread thread = new Thread(runnable); thread.start(); }
cdOrder.countDown();計數器減一 cdOrder.await();計數器爲0時候觸發
final Exchanger<String> exchanger = new Exchanger<>(); for(int i=0;i<2;i++){ Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { System.out.println("start-"+Thread.currentThread().getName()); System.out.println(exchanger.exchange(Thread.currentThread().getName())+Thread.currentThread().getName()); System.out.println("end-"+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread thread = new Thread(runnable); thread.start(); }
隊列是一種數據結構.它有兩個基本操做:在隊列尾部加人一個元素,和從隊列頭部移除一個元素就是說,隊列以一種先進先出的方式管理數據。Queue接口與List、Set同一級別,都是繼承了Collection接口。LinkedList實現了Queue接口。Queue接口窄化 了對LinkedList的方法的訪問權限(即在方法中的參數類型若是是Queue時,就徹底只能訪問Queue接口所定義的方法了,而不能直接訪問 LinkedList的非Queue的方法),以使得只有恰當的方法纔可使用。BlockingQueue 繼承了Queue接口。
幾種阻塞隊列:
LinkedBlockingQueue的容量默認是沒有上限的(在不指定時容量爲Integer.MAX_VALUE),也能夠選擇指定其最大容量,它是基於鏈表的隊列,此隊列按 FIFO(先進先出)排序元素。
ArrayBlockingQueue在構造時須要指定容量,並能夠選擇是否須要公平性(默認false),若是公平參數 被設置true,等待時間最長的線程會優先獲得處理(其實就是經過將ReentrantLock設置爲true來達到這種公平性的:即等待時間最長的線程 會先操做)。一般,公平性會使你在性能上付出代價,只有在的確很是須要的時候再使用它。它是基於數組的阻塞循環隊列,此隊列按 FIFO(先進先出)原則對元素進行排序。
PriorityBlockingQueue是一個帶優先級的隊列,而不是先進先出隊列。元素按優先級 順序被移除,該隊列也沒有上限(看了一下源碼,PriorityBlockingQueue是對PriorityQueue的再次包裝,是基於堆數據結構 的,而PriorityQueue是沒有容量限制的,與ArrayList同樣,因此在優先阻塞隊列上put時是不會受阻的,可是若是隊列爲空,取元素的操做take就會阻塞。另外,往入該隊列中的元 素要具備比較能力。
DelayQueue(基於PriorityQueue來實現的)是一個存放Delayed 元素的無界阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部是延遲期滿後保存時間最長的 Delayed 元素。若是延遲都尚未期滿,則隊列沒有頭部,而且poll將返回null。當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於或等於零的值時,則出現期滿,poll就以移除這個元素了。此隊列不容許使用 null 元素。
Collections工具類
注意:在集合的迭代過程當中,不能對集合進行刪除操做 這個時候能夠用CopyOnWriteArrayList