小葵花妈妈课堂开课了:《Runnable、Callable、Future、RunnableFuture、FutureTask 源码分析》
生活随笔
收集整理的這篇文章主要介紹了
小葵花妈妈课堂开课了:《Runnable、Callable、Future、RunnableFuture、FutureTask 源码分析》
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
先看一下官方介紹:
/*** Runnable接口 被任意class實現的實例,都是由thread去執行的。* 該類必須要實現一個無參的run方法。* 當runnable被激活時將要執行的代碼。* 例如實現了Runnable接口的Thread類。* 激活簡單來說就是thread已經開始執行并且沒有被停止。* 此外,Runnable提供給class的是接口方法來激活,而不是Thread去繼承。* 在沒有繼承Thread類的情形下可以通過實例化的線程去執行實現了Runnable的類。* 在大多數情況下,如果你計劃重寫run方法并且沒有其他線程方法,那么runnable接口就應該被使用。* 這樣做是重要的,因為類不能被繼承,除非開發人員打算修改或是增強類的功能。*/下面是原文:
/*** The <code>Runnable</code> interface should be implemented by any* class whose instances are intended to be executed by a thread. The* class must define a method of no arguments called <code>run</code>.* <p>* This interface is designed to provide a common protocol for objects that* wish to execute code while they are active. For example,* <code>Runnable</code> is implemented by class <code>Thread</code>.* Being active simply means that a thread has been started and has not* yet been stopped.* <p>* In addition, <code>Runnable</code> provides the means for a class to be* active while not subclassing <code>Thread</code>. A class that implements* <code>Runnable</code> can run without subclassing <code>Thread</code>* by instantiating a <code>Thread</code> instance and passing itself in* as the target. In most cases, the <code>Runnable</code> interface should* be used if you are only planning to override the <code>run()</code>* method and no other <code>Thread</code> methods.* This is important because classes should not be subclassed* unless the programmer intends on modifying or enhancing the fundamental* behavior of the class.** @author Arthur van Hoff* @see java.lang.Thread* @see java.util.concurrent.Callable* @since JDK1.0*/ /*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see java.lang.Thread#run()*/ /*** 當一個對象實現了Runnable接口用來創建一個線程,啟動線程會引起對象的run方法在制定的線程中執行。* run方法可以執行任何action.* run方法沒有返回值。*/ public abstract void run();再看一下Callable的官方介紹:
/*** task會返回一個結果并且可能拋出異常。* 定義了一個單一的無參的方法叫做call。* Callable接口類似于Runnable, 都是設計成為由另一個線程執行。* Runnable無論如何都不能返回結果并且也不能拋出異常。* * Executors類包含了實用的方法來轉換從其他常見形式轉換為Callable類。*/下面是原文:
/*** A task that returns a result and may throw an exception.* Implementors define a single method with no arguments called* {@code call}.** <p>The {@code Callable} interface is similar to {@link* java.lang.Runnable}, in that both are designed for classes whose* instances are potentially executed by another thread. A* {@code Runnable}, however, does not return a result and cannot* throw a checked exception.** <p>The {@link Executors} class contains utility methods to* convert from other common forms to {@code Callable} classes.** @see Executor* @since 1.5* @author Doug Lea* @param <V> the result type of method {@code call}*/ @FunctionalInterface public interface Callable<V> {/*** Computes a result, or throws an exception if unable to do so.** @return computed result* @throws Exception if unable to compute a result*//*** call方法會返回結果,如果不能計算出結果的話會拋出異常。*/V call() throws Exception; }通過官方解釋可以看出:
共同點:
- Runnable和Callable都是用Thread去執行
區別:
- Runnable沒有返回值,不會拋出異常
- Callable有返回值,會拋出異常
Future
官方介紹:
原文:
/*** A {@code Future} represents the result of an asynchronous* computation. Methods are provided to check if the computation is* complete, to wait for its completion, and to retrieve the result of* the computation. The result can only be retrieved using method* {@code get} when the computation has completed, blocking if* necessary until it is ready. Cancellation is performed by the* {@code cancel} method. Additional methods are provided to* determine if the task completed normally or was cancelled. Once a* computation has completed, the computation cannot be cancelled.* If you would like to use a {@code Future} for the sake* of cancellability but not provide a usable result, you can* declare types of the form {@code Future<?>} and* return {@code null} as a result of the underlying task.** <p>* <b>Sample Usage</b> (Note that the following classes are all* made-up.)** <pre> {@code* interface ArchiveSearcher { String search(String target); }* class App {* ExecutorService executor = ...* ArchiveSearcher searcher = ...* void showSearch(final String target)* throws InterruptedException {* Future<String> future* = executor.submit(new Callable<String>() {* public String call() {* return searcher.search(target);* }});* displayOtherThings(); // do other things while searching* try {* displayText(future.get()); // use future* } catch (ExecutionException ex) { cleanup(); return; }* }* }}</pre>** The {@link FutureTask} class is an implementation of {@code Future} that* implements {@code Runnable}, and so may be executed by an {@code Executor}.* For example, the above construction with {@code submit} could be replaced by:* <pre> {@code* FutureTask<String> future =* new FutureTask<>(new Callable<String>() {* public String call() {* return searcher.search(target);* }});* executor.execute(future);}</pre>** <p>Memory consistency effects: Actions taken by the asynchronous computation* <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>* actions following the corresponding {@code Future.get()} in another thread.** @see FutureTask* @see Executor* @since 1.5* @author Doug Lea* @param <V> The result type returned by this Future's {@code get} method*/介紹接口定義:
public interface Future<V> {/*** Attempts to cancel execution of this task. This attempt will* fail if the task has already completed, has already been cancelled,* or could not be cancelled for some other reason. If successful,* and this task has not started when {@code cancel} is called,* this task should never run. If the task has already started,* then the {@code mayInterruptIfRunning} parameter determines* whether the thread executing this task should be interrupted in* an attempt to stop the task.** <p>After this method returns, subsequent calls to {@link #isDone} will* always return {@code true}. Subsequent calls to {@link #isCancelled}* will always return {@code true} if this method returned {@code true}.** @param mayInterruptIfRunning {@code true} if the thread executing this* task should be interrupted; otherwise, in-progress tasks are allowed* to complete* @return {@code false} if the task could not be cancelled,* typically because it has already completed normally;* {@code true} otherwise*//*** 該方法為取消在執行的task,* 如果計算已經完成或者已經取消再或者因為其他原因不能取消,則取消失敗。* 如果成功,并且在調用cancel取消時,還沒有開始,task就不會在執行了。* 如果task已經開始了,那么mayInterruptIfRunning這個參數就會決定,執行任務的線程是否嘗試中斷task.* 當該方法cancel返回結果后,后來在調用isDone將一直返回true。* 之后在調用isCancelled會一直返回true,如果cancel之前返回true。正在進行的task仍會繼續計算。* * 如果結果返回false 也就是取消失敗,通常是因為他已經正常結束了。* * mayInterruptIfRunning 參數如果為true, 則執行task的線程會中斷;否則*/boolean cancel(boolean mayInterruptIfRunning);/*** Returns {@code true} if this task was cancelled before it completed* normally.** @return {@code true} if this task was cancelled before it completed* 如果在任務正常結束之前調用了cancel 那么會返回true。*/boolean isCancelled();/*** Returns {@code true} if this task completed.** Completion may be due to normal termination, an exception, or* cancellation -- in all of these cases, this method will return* {@code true}.* * 如果過task計算完成則返回true。* 計算也許是正常結束,也許異常結束,或許被取消, 這些情況該方法都會返回true。* * @return {@code true} if this task completed*/boolean isDone();/*** Waits if necessary for the computation to complete, and then* retrieves its result.* * 必要時就會等待計算完成,并且返回計算結果。* * @return the computed result* @throws CancellationException if the computation was cancelled* 如果計算被取消* @throws ExecutionException if the computation threw an* exception* 如果計算拋出異常* @throws InterruptedException if the current thread was interrupted* while waiting* 如果在等待時線程唄中斷則會跑異常*/V get() throws InterruptedException, ExecutionException;/*** Waits if necessary for at most the given time for the computation* to complete, and then retrieves its result, if available.* * 需要等待時,會最多等待給定的時長,并返回結果。* * @param timeout the maximum time to wait* @param unit the time unit of the timeout argument* @return the computed result* @throws CancellationException if the computation was cancelled* @throws ExecutionException if the computation threw an* exception* @throws InterruptedException if the current thread was interrupted* while waiting* @throws TimeoutException if the wait timed out*/V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException; }RunnableFuture
/*** A {@link Future} that is {@link Runnable}. Successful execution of* the {@code run} method causes completion of the {@code Future}* and allows access to its results.* @see FutureTask* @see Executor* @since 1.6* @author Doug Lea* @param <V> The result type returned by this Future's {@code get} method*///Futrue即為Runnable。因為繼承Future所以可以執行run方法。//并且可以接受返回的結果。 public interface RunnableFuture<V> extends Runnable, Future<V> {/*** Sets this Future to the result of its computation* unless it has been cancelled.*/void run(); }FutureTask
FutureTask 實現了RunnableFutrue接口
官方介紹:
解析FutureTask
public class FutureTask<V> implements RunnableFuture<V> {/** Revision notes: This differs from previous versions of this* class that relied on AbstractQueuedSynchronizer, mainly to* avoid surprising users about retaining interrupt status during* cancellation races. Sync control in the current design relies* on a "state" field updated via CAS to track completion, along* with a simple Treiber stack to hold waiting threads.** Style note: As usual, we bypass overhead of using* AtomicXFieldUpdaters and instead directly use Unsafe intrinsics.*//*** 版本標注:不同于之前的版本,當前類依靠AbstractQueuedSynchronizer,* 主要是為了避免用戶關于始終保持中斷狀態在取消的時候。在當前設計中同步控制* 依賴于state字段,該字段通過CAS更新,并和Treiber棧去持有等待線程。*//*** The run state of this task, initially NEW. The run state* transitions to a terminal state only in methods set,* setException, and cancel. During completion, state may take on* transient values of COMPLETING (while outcome is being set) or* INTERRUPTING (only while interrupting the runner to satisfy a* cancel(true)). Transitions from these intermediate to final* states use cheaper ordered/lazy writes because values are unique* and cannot be further modified.** Possible state transitions:* NEW -> COMPLETING -> NORMAL* NEW -> COMPLETING -> EXCEPTIONAL* NEW -> CANCELLED* NEW -> INTERRUPTING -> INTERRUPTED*//*** 這個task的運行狀態,初始化為NEW。* 僅能通過set,setException和cancel將運行狀態轉變為中斷狀態。* 在計算時候,state可以呈現出COMPLETING的值(雖然結果正在設定)或者INTERRUPTING的值* (僅當使用中斷來取消的時候)* 使用廉價的命令和懶寫入從中間狀態過度到最終狀態,因為值是唯一的并且不能進一步修改。* 可能存在的狀態轉化情況:* NEW -> COMPLETING -> NORMAL* NEW -> COMPLETING -> EXCEPTIONAL* NEW -> CANCELLED* NEW -> INTERRUPTING -> INTERRUPTED*/private volatile int state;private static final int NEW = 0;private static final int COMPLETING = 1;private static final int NORMAL = 2;private static final int EXCEPTIONAL = 3;private static final int CANCELLED = 4;private static final int INTERRUPTING = 5;private static final int INTERRUPTED = 6;/** The underlying callable; nulled out after running */// 底層調用callable;清零后調用private Callable<V> callable;/** The result to return or exception to throw from get() *///返回額結果或者是get()拋出的異常 非volatile ,通過reads/writes狀態來保護安全性private Object outcome; // non-volatile, protected by state reads/writes/** The thread running the callable; CASed during run() */private volatile Thread runner;/** Treiber stack of waiting threads */private volatile WaitNode waiters;/*** Returns result or throws exception for completed task.** @param s completed state value*/@SuppressWarnings("unchecked")private V report(int s) throws ExecutionException {Object x = outcome;if (s == NORMAL)return (V)x;if (s >= CANCELLED)throw new CancellationException();throw new ExecutionException((Throwable)x);}/*** Creates a {@code FutureTask} that will, upon running, execute the* given {@code Callable}.** @param callable the callable task* @throws NullPointerException if the callable is null*/public FutureTask(Callable<V> callable) {if (callable == null)throw new NullPointerException();this.callable = callable;this.state = NEW; // ensure visibility of callable}/*** Creates a {@code FutureTask} that will, upon running, execute the* given {@code Runnable}, and arrange that {@code get} will return the* given result on successful completion.** @param runnable the runnable task* @param result the result to return on successful completion. If* you don't need a particular result, consider using* constructions of the form:* {@code Future<?> f = new FutureTask<Void>(runnable, null)}* @throws NullPointerException if the runnable is null*/public FutureTask(Runnable runnable, V result) {this.callable = Executors.callable(runnable, result);this.state = NEW; // ensure visibility of callable}public boolean isCancelled() {return state >= CANCELLED;}public boolean isDone() {return state != NEW;}public boolean cancel(boolean mayInterruptIfRunning) {if (!(state == NEW &&U.compareAndSwapInt(this, STATE, NEW,mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))return false;try { // in case call to interrupt throws exceptionif (mayInterruptIfRunning) {try {Thread t = runner;if (t != null)t.interrupt();} finally { // final stateU.putOrderedInt(this, STATE, INTERRUPTED);}}} finally {finishCompletion();}return true;}/*** @throws CancellationException {@inheritDoc}*/public V get() throws InterruptedException, ExecutionException {int s = state;if (s <= COMPLETING)s = awaitDone(false, 0L);return report(s);}/*** @throws CancellationException {@inheritDoc}*/public V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException {if (unit == null)throw new NullPointerException();int s = state;if (s <= COMPLETING &&(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)throw new TimeoutException();return report(s);}/*** Protected method invoked when this task transitions to state* {@code isDone} (whether normally or via cancellation). The* default implementation does nothing. Subclasses may override* this method to invoke completion callbacks or perform* bookkeeping. Note that you can query status inside the* implementation of this method to determine whether this task* has been cancelled.*/protected void done() { }/*** Sets the result of this future to the given value unless* this future has already been set or has been cancelled.** <p>This method is invoked internally by the {@link #run} method* upon successful completion of the computation.** @param v the value*/protected void set(V v) {if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {outcome = v;U.putOrderedInt(this, STATE, NORMAL); // final statefinishCompletion();}}/*** Causes this future to report an {@link ExecutionException}* with the given throwable as its cause, unless this future has* already been set or has been cancelled.** <p>This method is invoked internally by the {@link #run} method* upon failure of the computation.** @param t the cause of failure*/protected void setException(Throwable t) {if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {outcome = t;U.putOrderedInt(this, STATE, EXCEPTIONAL); // final statefinishCompletion();}}public void run() {if (state != NEW ||!U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))return;try {Callable<V> c = callable;if (c != null && state == NEW) {V result;boolean ran;try {result = c.call();ran = true;} catch (Throwable ex) {result = null;ran = false;setException(ex);}if (ran)set(result);}} finally {// runner must be non-null until state is settled to// prevent concurrent calls to run()runner = null;// state must be re-read after nulling runner to prevent// leaked interruptsint s = state;if (s >= INTERRUPTING)handlePossibleCancellationInterrupt(s);}}/*** Executes the computation without setting its result, and then* resets this future to initial state, failing to do so if the* computation encounters an exception or is cancelled. This is* designed for use with tasks that intrinsically execute more* than once.** @return {@code true} if successfully run and reset*/protected boolean runAndReset() {if (state != NEW ||!U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))return false;boolean ran = false;int s = state;try {Callable<V> c = callable;if (c != null && s == NEW) {try {c.call(); // don't set resultran = true;} catch (Throwable ex) {setException(ex);}}} finally {// runner must be non-null until state is settled to// prevent concurrent calls to run()runner = null;// state must be re-read after nulling runner to prevent// leaked interruptss = state;if (s >= INTERRUPTING)handlePossibleCancellationInterrupt(s);}return ran && s == NEW;}/*** Ensures that any interrupt from a possible cancel(true) is only* delivered to a task while in run or runAndReset.*/private void handlePossibleCancellationInterrupt(int s) {// It is possible for our interrupter to stall before getting a// chance to interrupt us. Let's spin-wait patiently.if (s == INTERRUPTING)while (state == INTERRUPTING)Thread.yield(); // wait out pending interrupt// assert state == INTERRUPTED;// We want to clear any interrupt we may have received from// cancel(true). However, it is permissible to use interrupts// as an independent mechanism for a task to communicate with// its caller, and there is no way to clear only the// cancellation interrupt.//// Thread.interrupted();}/*** Simple linked list nodes to record waiting threads in a Treiber* stack. See other classes such as Phaser and SynchronousQueue* for more detailed explanation.*/static final class WaitNode {volatile Thread thread;volatile WaitNode next;WaitNode() { thread = Thread.currentThread(); }}/*** Removes and signals all waiting threads, invokes done(), and* nulls out callable.*/private void finishCompletion() {// assert state > COMPLETING;for (WaitNode q; (q = waiters) != null;) {if (U.compareAndSwapObject(this, WAITERS, q, null)) {for (;;) {Thread t = q.thread;if (t != null) {q.thread = null;LockSupport.unpark(t);}WaitNode next = q.next;if (next == null)break;q.next = null; // unlink to help gcq = next;}break;}}done();callable = null; // to reduce footprint}/*** Awaits completion or aborts on interrupt or timeout.** @param timed true if use timed waits* @param nanos time to wait, if timed* @return state upon completion or at timeout*/private int awaitDone(boolean timed, long nanos)throws InterruptedException {// The code below is very delicate, to achieve these goals:// - call nanoTime exactly once for each call to park// - if nanos <= 0L, return promptly without allocation or nanoTime// - if nanos == Long.MIN_VALUE, don't underflow// - if nanos == Long.MAX_VALUE, and nanoTime is non-monotonic// and we suffer a spurious wakeup, we will do no worse than// to park-spin for a whilelong startTime = 0L; // Special value 0L means not yet parkedWaitNode q = null;boolean queued = false;for (;;) {int s = state;if (s > COMPLETING) {if (q != null)q.thread = null;return s;}else if (s == COMPLETING)// We may have already promised (via isDone) that we are done// so never return empty-handed or throw InterruptedExceptionThread.yield();else if (Thread.interrupted()) {removeWaiter(q);throw new InterruptedException();}else if (q == null) {if (timed && nanos <= 0L)return s;q = new WaitNode();}else if (!queued)queued = U.compareAndSwapObject(this, WAITERS,q.next = waiters, q);else if (timed) {final long parkNanos;if (startTime == 0L) { // first timestartTime = System.nanoTime();if (startTime == 0L)startTime = 1L;parkNanos = nanos;} else {long elapsed = System.nanoTime() - startTime;if (elapsed >= nanos) {removeWaiter(q);return state;}parkNanos = nanos - elapsed;}// nanoTime may be slow; recheck before parkingif (state < COMPLETING)LockSupport.parkNanos(this, parkNanos);}elseLockSupport.park(this);}}/*** Tries to unlink a timed-out or interrupted wait node to avoid* accumulating garbage. Internal nodes are simply unspliced* without CAS since it is harmless if they are traversed anyway* by releasers. To avoid effects of unsplicing from already* removed nodes, the list is retraversed in case of an apparent* race. This is slow when there are a lot of nodes, but we don't* expect lists to be long enough to outweigh higher-overhead* schemes.*/private void removeWaiter(WaitNode node) {if (node != null) {node.thread = null;retry:for (;;) { // restart on removeWaiter racefor (WaitNode pred = null, q = waiters, s; q != null; q = s) {s = q.next;if (q.thread != null)pred = q;else if (pred != null) {pred.next = s;if (pred.thread == null) // check for racecontinue retry;}else if (!U.compareAndSwapObject(this, WAITERS, q, s))continue retry;}break;}}}// Unsafe mechanicsprivate static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();private static final long STATE;private static final long RUNNER;private static final long WAITERS;static {try {STATE = U.objectFieldOffset(FutureTask.class.getDeclaredField("state"));RUNNER = U.objectFieldOffset(FutureTask.class.getDeclaredField("runner"));WAITERS = U.objectFieldOffset(FutureTask.class.getDeclaredField("waiters"));} catch (ReflectiveOperationException e) {throw new Error(e);}// Reduce the risk of rare disastrous classloading in first call to// LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773Class<?> ensureLoaded = LockSupport.class;}}Thanks
總結
以上是生活随笔為你收集整理的小葵花妈妈课堂开课了:《Runnable、Callable、Future、RunnableFuture、FutureTask 源码分析》的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 类似win7系统泡泡屏保
- 下一篇: 调用百度地图进行路线规划