對於高級任務的併發,需要高層併發對象來充分利用多處理器和多核的大規模併發應用。主要在包java.util.concurrent。
鎖Lock
public interface Lock {
//用來獲取鎖。如果鎖是不可用則線程等待直到獲取到鎖。
void lock();
/**
//如果當前線程沒有被中斷獲取鎖。
//如果鎖是可用的,請求鎖並馬上返回;如果鎖不可用,當前線程就不能完成線程調度,然後開始休眠直到當前線程獲取鎖成功或響應被另一個線程中斷。
//如果當前線程在這個方法裏設置它的中斷狀態,或者在獲取鎖的時候當前線程響應了中斷鎖的請求,就會拋出中斷異常InterruptedException清除當前線程的中斷狀態。
*/
void lockInterruptibly() throws InterruptedException;
/**
//只要在調用這個方法的時候是自由的就請求鎖。
//如果鎖是可用的,請求鎖並馬上返回true;如果不可用直接返回false。
//這個方法的經典使用例子如下,這種使用可以確保在請求到鎖時鎖被釋放,沒有請求到鎖時不會去試圖釋放鎖。
Lock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}}
*/
boolean tryLock();
/**
//在給定時間裏當前線程是自由的並且沒有被中斷就請求鎖。
//如果鎖是可用的,請求鎖並馬上返回true;如果不可用當前線程就不能達到調度線程目的,然後開始休眠直到當前線程獲取到鎖或者其他線程中斷了它,再或者到了指定的時間。
//中斷異常拋出情況同lockInterruptibly()
*/
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unLock();//釋放鎖
Condition newCondition();//返回一個綁定這個鎖的條件實例
}
public interface ReadWriteLock {
/**
* 返回用於讀的鎖
*/
Lock readLock();
/**
* 返回用於寫的鎖
*/
Lock writeLock();
}
線程池
1.Executors
使用靜態工廠方法生成一些常用線程池
public class Executors {
/**
* nThread:線程池的線程個數
* threadFactory:當創建新的線程時使用的工廠,下面每個方法都有個重載方法,少了這個參數,當沒有此參數時爲默認工廠defaultThreadFactory()提供。
*/
//創建使用固定大小線程池的執行器。
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory);
}
}
//創建使用可擴展的線程池的執行器,適合執行大量短時任務
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),threadFactory);
}
//創建一個一次執行一個任務的執行器。
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory));
}
//創建一個默認線程工廠
public static ThreadFactory defaultThreadFactory() {
return new DefaultThreadFactory();
}
2.Executor
用來運行提交的任務棧的簡單接口。
public interface Executor {
/**
* 在將來某個時刻運行這些給定的命令行。
* 這個命令可能運行在一個新的線程或者一個線程池再或者一個調用它的線程裏, 由Executor得實例處理。
* @param command 任務棧
* @throws RejectedExecutionException 如果這個任務不能被運行就會拋出
* @throws NullPointerException 如果command爲null拋出
*/
void execute(Runnable command);
}
3.ExecutorService
在Executor基礎上增加一些方法來管理生命週期,管理執行器關閉。
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();//如果這個executor被關閉就返回true
boolean isTerminated();
<T> Future<T> submit(...);
<T> List<Future<T>> invokeAll(...);
}
AdstractExecutorService是ExecutorService的一種默認實現
4.ExecutorPoolExecutor
線程池剛創建時裏面是沒有線程的,需提交任務纔會創建線程,也可調用特定方法立即創建。
public class ThreadPoolExecutor extends AbstractExecutorService {
/**
* 有四個重載的構造方法,這是參數最多的一個。
* corePoolSize:核心池大小,線程數目大於這個數時提交的任務就會被放進緩存隊列。
* maximumPoolSize:線程池最大線程數,可動態調整。
* keepAliveTime:線程無任務執行時最多保持多久時間終止。當線程數大於corePoolSize時或給核心線程池的線程設時間時纔會起作用。
* unit:time的時間單位,有七種,如TimeUnit.DAYS
* workQueue:緩存隊列,存儲等待執行的任務,一般選LinkedBlockingQueue或Synchronous。
* threadFactory:線程工廠,用來創建線程。
* handler:當拒絕處理任務時的策略,4種取值。
* 若當前線程數<corePoolSize,就每來一個任務創建一個線程;
* 若當前線程數>=corePoolSize,就嘗試將任務加入BlockingQueue,如果加入失敗一般來說就是緩存隊列已滿,那就再創建新線程。
* 若當前線程數>maximumPoolSize,就會採取任務拒絕策略來處理。
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
}
//線程池的運行狀態
private static final int RUNNING = -1 << COUNT_BITS; //創建線程初始時。
private static final int SHUTDOWN = 0 << COUNT_BITS;//調用shutDown()時,此時線程池不接受新任務,會等待所有任務執行完畢。
private static final int STOP = 1 << COUNT_BITS;//調用shutDownNow()時,此時線程池不接受新任務,並且會嘗試終止正在執行的任務。
private static final int TIDYING = 2 << COUNT_BITS;//
private static final int TERMINATED = 3 << COUNT_BITS;//當線程處於SHUTDOWN和STOP狀態,所有工程線程銷燬,任務緩存隊列也清空或結束時。
}