executor 線程池
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
execute方法代表執(zhí)行,需要傳入一個Runnable,自動執(zhí)行
public interface ExecutorService extends Executor {
/**
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
* Invocation has no additional effect if already shut down.
*
* <p>This method does not wait for previously submitted tasks to
* complete execution. Use {@link #awaitTermination awaitTermination}
* to do that.
*/
void shutdown();
/**
* Attempts to stop all actively executing tasks, halts the
* processing of waiting tasks, and returns a list of the tasks
* that were awaiting execution.
*
* <p>This method does not wait for actively executing tasks to
* terminate. Use {@link #awaitTermination awaitTermination} to
* do that.
*
* <p>There are no guarantees beyond best-effort attempts to stop
* processing actively executing tasks. For example, typical
* implementations will cancel via {@link Thread#interrupt}, so any
* task that fails to respond to interrupts may never terminate.
*
* @return list of tasks that never commenced execution
*/
List<Runnable> shutdownNow();
/**
* Returns {@code true} if this executor has been shut down.
*
* @return {@code true} if this executor has been shut down
*/
boolean isShutdown();
/**
* Returns {@code true} if all tasks have completed following shut down.
* Note that {@code isTerminated} is never {@code true} unless
* either {@code shutdown} or {@code shutdownNow} was called first.
*
* @return {@code true} if all tasks have completed following shut down
*/
boolean isTerminated();
/**
* Blocks until all tasks have completed execution after a shutdown
* request, or the timeout occurs, or the current thread is
* interrupted, whichever happens first.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return {@code true} if this executor terminated and
* {@code false} if the timeout elapsed before termination
* @throws InterruptedException if interrupted while waiting
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
/**
* Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The
* Future's {@code get} method will return the task's result upon
* successful completion.
*
* <p>
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* {@code result = exec.submit(aCallable).get();}
*
* <p>Note: The {@link Executors} class includes a set of methods
* that can convert some other common closure-like objects,
* for example, {@link java.security.PrivilegedAction} to
* {@link Callable} form so they can be submitted.
*
* @param task the task to submit
* @param <T> the type of the task's result
* @return a Future representing pending completion of the task
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if the task is null
*/
<T> Future<T> submit(Callable<T> task);
/**
* Submits a Runnable task for execution and returns a Future
* representing that task. The Future's {@code get} method will
* return the given result upon successful completion.
*
* @param task the task to submit
* @param result the result to return
* @param <T> the type of the result
* @return a Future representing pending completion of the task
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if the task is null
*/
<T> Future<T> submit(Runnable task, T result);
/**
* Submits a Runnable task for execution and returns a Future
* representing that task. The Future's {@code get} method will
* return {@code null} upon <em>successful</em> completion.
*
* @param task the task to submit
* @return a Future representing pending completion of the task
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if the task is null
*/
Future<?> submit(Runnable task);
/**
* Executes the given tasks, returning a list of Futures holding
* their status and results when all complete.
* {@link Future#isDone} is {@code true} for each
* element of the returned list.
* Note that a <em>completed</em> task could have
* terminated either normally or by throwing an exception.
* The results of this method are undefined if the given
* collection is modified while this operation is in progress.
*
* @param tasks the collection of tasks
* @param <T> the type of the values returned from the tasks
* @return a list of Futures representing the tasks, in the same
* sequential order as produced by the iterator for the
* given task list, each of which has completed
* @throws InterruptedException if interrupted while waiting, in
* which case unfinished tasks are cancelled
* @throws NullPointerException if tasks or any of its elements are {@code null}
* @throws RejectedExecutionException if any task cannot be
* scheduled for execution
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
/**
* Executes the given tasks, returning a list of Futures holding
* their status and results
* when all complete or the timeout expires, whichever happens first.
* {@link Future#isDone} is {@code true} for each
* element of the returned list.
* Upon return, tasks that have not completed are cancelled.
* Note that a <em>completed</em> task could have
* terminated either normally or by throwing an exception.
* The results of this method are undefined if the given
* collection is modified while this operation is in progress.
*
* @param tasks the collection of tasks
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @param <T> the type of the values returned from the tasks
* @return a list of Futures representing the tasks, in the same
* sequential order as produced by the iterator for the
* given task list. If the operation did not time out,
* each task will have completed. If it did time out, some
* of these tasks will not have completed.
* @throws InterruptedException if interrupted while waiting, in
* which case unfinished tasks are cancelled
* @throws NullPointerException if tasks, any of its elements, or
* unit are {@code null}
* @throws RejectedExecutionException if any task cannot be scheduled
* for execution
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
/**
* Executes the given tasks, returning the result
* of one that has completed successfully (i.e., without throwing
* an exception), if any do. Upon normal or exceptional return,
* tasks that have not completed are cancelled.
* The results of this method are undefined if the given
* collection is modified while this operation is in progress.
*
* @param tasks the collection of tasks
* @param <T> the type of the values returned from the tasks
* @return the result returned by one of the tasks
* @throws InterruptedException if interrupted while waiting
* @throws NullPointerException if tasks or any element task
* subject to execution is {@code null}
* @throws IllegalArgumentException if tasks is empty
* @throws ExecutionException if no task successfully completes
* @throws RejectedExecutionException if tasks cannot be scheduled
* for execution
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
/**
* Executes the given tasks, returning the result
* of one that has completed successfully (i.e., without throwing
* an exception), if any do before the given timeout elapses.
* Upon normal or exceptional return, tasks that have not
* completed are cancelled.
* The results of this method are undefined if the given
* collection is modified while this operation is in progress.
*
* @param tasks the collection of tasks
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @param <T> the type of the values returned from the tasks
* @return the result returned by one of the tasks
* @throws InterruptedException if interrupted while waiting
* @throws NullPointerException if tasks, or unit, or any element
* task subject to execution is {@code null}
* @throws TimeoutException if the given timeout elapses before
* any task successfully completes
* @throws ExecutionException if no task successfully completes
* @throws RejectedExecutionException if tasks cannot be scheduled
* for execution
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
主要三個方法
void shutdown();代表關閉線程池,不能再讓該線程池添加任務。但是在執(zhí)行中的任務和排隊中的任務不會受到影響,全部執(zhí)行完才會結(jié)束
List<Runnable> shutdownNow();代表結(jié)束線程池。會通過Thread.interrput()來試圖結(jié)束正在執(zhí)行的任務,隊列中的任務不會執(zhí)行,并且將其返回。也會等待所有任務都結(jié)束才會真正結(jié)束。
<T> Future<T> submit(Callable<T> task);代表執(zhí)行一個帶阻塞式的任務,可以使用Callable,拿到線程的返回值
ThreadPoolExecutor
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory and rejected execution handler.
* It may be more convenient to use one of the {@link Executors} factory
* methods instead of this general purpose constructor.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
corePoolSize代表默認線程個數(shù)。當線程池被創(chuàng)建,就默認創(chuàng)建多少個;當線程池在一個一個回收,回收都默認個數(shù)后就不會回收了
maximumPoolSize代表最大線程格數(shù)。當線程池中線程超過最大數(shù),就會進入排隊隊列中。
keepAliveTime & unit兩個一起使用,代表線程等待被回收的時間。當線程執(zhí)行完,具體多少后會被回收,取決與這個時間
workQueue代表任務隊列。當線程池中線程超過最大數(shù),再添加任務先添加到此隊列,等待線程被回收后,線程池當前線程數(shù)小于最大數(shù),將會取出執(zhí)行。
ThreadPoolExecutor 常用實現(xiàn)
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
代表一個可以添加無數(shù)個任務,默認線程數(shù)0,1分鐘會被回收的線程池。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
代表單線程的線程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
代表固定線程數(shù)的線程池,并且不會被回收,不能擴展。一般用來處理集中瞬時爆發(fā)的任務,之后需要調(diào)用shutdown()來結(jié)束且回收
線程同步與安全
本質(zhì)就是資源問題
volatile
當子線程使用了主線程的內(nèi)對象,其實子線程會把主線程的內(nèi)對象拷貝到自己的內(nèi)存塊,當子線程這個對象的值發(fā)送改變后,主線程中這個對象不會發(fā)送變化,JVM這樣做是為了效率問題。為主線程的內(nèi)對象加上volatile關鍵字,會讓此對象具有同步性,這個時候在子線程修改對象值的時候,會同步到主線程內(nèi)對象上,相反主線程修改也會同步到子線程。
ATomic
使用了volatile后,對象會有同步性,但是當修改這個值是需要分幾步執(zhí)行時??赡茉谛薷倪^程中切換到另一個線程從頭開始修改,導致了程序的數(shù)據(jù)錯亂。所以可以在Atomic來作為對象,比如++ --,讓修改操作不僅僅具有同步性,而且具有原子性。
synchronized
同步的意思,保護代碼塊在多線程同時調(diào)用的時候,具有原子性,不會出現(xiàn)數(shù)據(jù)錯誤。
monitor(鎖)
使用synchronized需要用到,可以理解為鎖。
當為代碼塊使用synchronized (this) {}, 會使用當前類對象的鎖。
當其他線程同時調(diào)用時,這個鎖還處于未解鎖,其他線程會在后面等待被執(zhí)行,直至鎖被解鎖,再執(zhí)行后面的線程任務。
當為代碼塊使用synchronized (${other monitor}) {},當其他線程同時調(diào)用時,執(zhí)行的方法中有這個鎖才會等待執(zhí)行,否則不受鎖限制。
死鎖
當A方法,代碼塊用了A鎖,A鎖中使用了B鎖;
當B方法,代碼塊用了B鎖,B鎖中使用了A鎖;
A線程調(diào)用A方法,B線程調(diào)用B方法,且同時調(diào)用。A執(zhí)行后A鎖會鎖住,B執(zhí)行后B鎖會鎖住。A鎖中執(zhí)行到B鎖的時候,發(fā)現(xiàn)B鎖鎖住了,就會等待解鎖;B鎖中執(zhí)行到A鎖的時候,發(fā)現(xiàn)A鎖鎖住了,也會等待解鎖。這樣就成死鎖了。
樂觀鎖悲觀鎖
這是操作數(shù)據(jù)庫才能的遇到的問題,一般在Android中不會出現(xiàn)
樂觀鎖的意思就是不加鎖,從數(shù)據(jù)庫拿了數(shù)據(jù)做業(yè)務邏輯修改數(shù)據(jù),存入數(shù)據(jù)庫的時候,再拿數(shù)據(jù)庫最新數(shù)據(jù)和當時拿出來的數(shù)據(jù)對比,值沒有被其他人修改就提價修改;值有差別,則再取出值重新做業(yè)務邏輯。
悲觀鎖的意思就是我從數(shù)據(jù)庫開始讀取數(shù)據(jù)的時候,我就加鎖,不允許其他人修改數(shù)據(jù)。我拿到數(shù)據(jù)處理完直接更新數(shù)據(jù)庫,之后我再解鎖,讓別人操作。
靜態(tài)鎖
一般用于單例模式
getInstance() 可能存在多線程同時調(diào)用,防止多次初始化并且覆蓋操作,需要加上靜態(tài)鎖
synchronized(Class.class)