標籤: javahtml
[TOC]java
本文主要概述java.util.concurrent
包下的相關類和使用方法git
java.util.concurrent.atomic
包下的類:api
幾種經常使用的的生成線程池的方法:併發
newCachedThreadPool
newFixedThreadPool
newScheduledThreadPool
newSingleThreadExecutor
newSingleThreadScheduledExecutor
例子:newFixedThreadPool
oracle
ExecutorService threadPool = Executors.newFixedThreadPool(3); for(int i=0;i<10;i++){ threadPool.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }); }
單線程newSingleThreadExecutor
可用於重啓ide
用線程池啓動定時器
例子:相似Timer的定時執行
Executors.newScheduledThreadPool(3).scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("ScheduledThreadPool "+Thread.currentThread().getName()); } },3,1, TimeUnit.SECONDS );
ExecutorService
在Executor
的基礎上增長了一些方法,其中有兩個核心的方法:
Future<?> submit(Runnable task)
<T> Future<T> submit(Callable<T> task)
這兩個方法都是向線程池中提交任務,它們的區別在於Runnable
在執行完畢後沒有結果,Callable
執行完畢後有一個結果。這在多個線程中傳遞狀態和結果是很是有用的。另外他們的相同點在於都返回一個Future對象。Future
對象能夠阻塞線程直到運行完畢(獲取結果,若是有的話),也能夠取消任務執行,固然也可以檢測任務是否被取消或者是否執行完畢。
Lock功能相似傳統多線程技術裏的synchronized
,實現線程互斥,但更加面向對象。將須要互斥的代碼片斷放到lock.lock();
和lock.unlock();
之間。
例子
class A{ private Lock lock = new ReentrantLock(); public void function(){ lock.lock(); try{ //功能代碼 }finally{ lock.unlock(); } } }
javaDoc文檔讀寫鎖例子,緩存:
class CachedData { Object data; volatile boolean cacheValid; final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); } finally { rwl.writeLock().unlock(); // Unlock write, still hold read } } try { use(data); } finally { rwl.readLock().unlock(); } } }
重點注意在釋放寫鎖前加讀鎖那部分代碼,註釋爲 // Downgrade by acquiring read lock before releasing write lock
。本身掛了寫鎖,再掛讀鎖是能夠的,這面涉及的技巧之後再研究。
Condition相似於傳統多線程技術中的Object.wait
和Object.notify
,實現線程間同步。
javaDoc文檔例子,可阻塞隊列
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
使用了兩個condition
Semaphore
相似佔坑
CyclicBarrier
階段性使進度一致
CountDownLatch
一人通知多人/多人通知一人
Exchanger
線程間數據交換,都到達則天然交換