Java中RunnableFuture接口的作用是啥
最近也在看Java并发框架,Callable 、Future、RunnableFuture、FutureTask、Sync、ThreadPoolExecutor等类可以放在一起研究,重点关注callbale接口返回对象以及对线程相关操作的处理上。要注意:RunnableFuture接口是继承了Runnable和Future接口的package java.util.concurrent;public interface Future\u0026lt;V\u0026gt; { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}package java.lang;public interface Runnable { public abstract void run();}在我们调用ThreadPoolExecutor当中的submit方法的时候 public Future\u0026lt;?\u0026gt; submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture\u0026lt;Object\u0026gt; ftask = newTaskFor(task, null); execute(ftask); return ftask; } public \u0026lt;T\u0026gt; Future\u0026lt;T\u0026gt; submit(Runnable task, T result) { if (task == null) throw new NullPointerException(); RunnableFuture\u0026lt;T\u0026gt; ftask = newTaskFor(task, result); execute(ftask); return ftask; } public \u0026lt;T\u0026gt; Future\u0026lt;T\u0026gt; submit(Callable\u0026lt;T\u0026gt; task) { if (task == null) throw new NullPointerException(); RunnableFuture\u0026lt;T\u0026gt; ftask = newTaskFor(task); execute(ftask); return ftask; }其实该方法是有三个重载的,既可以submit Callable对象也可以submit Runnable对象 也可以submit Runnable对象同时附加返回值。而FutureTask对象是RunnableFuture接口的实现public class FutureTask\u0026lt;V\u0026gt; implements RunnableFuture\u0026lt;V\u0026gt;注意,在submit的时候线程池最终还是调用的ThreadPoolExecutor的execute(Runnable runnable)方法实现的,因此我们是将Callable对象封装在FutureTask对象当中,由于FutureTask对象实现了RunnableFuture接口,也是个Runnable对象,最后返回的也是这个FutureTask对象。 RunnableFuture\u0026lt;T\u0026gt; ftask = newTaskFor(task); execute(ftask); return ftask;关键就是在于生成的FutureTask对象的额run方法开始。package java.util.concurrent;import java.util.concurrent.locks.*;public class FutureTask\u0026lt;V\u0026gt; implements RunnableFuture\u0026lt;V\u0026gt; { private final Sync sync; public FutureTask(Callable\u0026lt;V\u0026gt; callable) { if (callable == null) throw new NullPointerException(); sync = new Sync(callable); } public FutureTask(Runnable runnable, V result) { sync = new Sync(Executors.callable(runnable, result)); } public boolean isCancelled() { return sync.innerIsCancelled(); } public boolean isDone() { return sync.innerIsDone(); } public boolean cancel(boolean mayInterruptIfRunning) { return sync.innerCancel(mayInterruptIfRunning); } /** * @throws CancellationException {@inheritDoc} */ public V get() throws InterruptedException, ExecutionException { return sync.innerGet(); } public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return sync.innerGet(unit.toNanos(timeout)); } protected void done() { } protected void set(V v) { sync.innerSet(v); } protected void setException(Throwable t) { sync.innerSetException(t); } public void run() { sync.innerRun(); } protected boolean runAndReset() { return sync.innerRunAndReset(); } private final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -7828117401763700385L; private static final int RUNNING = 1; private static final int RAN = 2; private static final int CANCELLED = 4; private final Callable\u0026lt;V\u0026gt; callable; private V result; private Throwable exception; private volatile Thread runner; Sync(Callable\u0026lt;V\u0026gt; callable) { this.callable = callable; } private boolean ranOrCancelled(int state) { return (state \u0026amp; (RAN | CANCELLED)) != 0; } /** * Implements AQS base acquire to succeed if ran or cancelled */ protected int tryAcquireShared(int ignore) { return innerIsDone()? 1 : -1; } protected boolean tryReleaseShared(int ignore) { runner = null; return true; } boolean innerIsCancelled() { return getState() == CANCELLED; } boolean innerIsDone() { return ranOrCancelled(getState()) \u0026amp;\u0026amp; runner == null; } V innerGet() throws InterruptedException, ExecutionException { acquireSharedInterruptibly(0); if (getState() == CANCELLED) throw new CancellationException(); if (exception != null) throw new ExecutionException(exception); return result; } V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException { if (!tryAcquireSharedNanos(0, nanosTimeout)) throw new TimeoutException(); if (getState() == CANCELLED) throw new CancellationException(); if (exception != null) throw new ExecutionException(exception); return result; } void innerSet(V v) {\t for (;;) {\t\tint s = getState();\t\tif (s == RAN)\t\t return; if (s == CANCELLED) {\t\t // aggressively release to set runner to null,\t\t // in case we are racing with a cancel request\t\t // that will try to interrupt runner releaseShared(0); return; }\t\tif (compareAndSetState(s, RAN)) { result = v; releaseShared(0); done();\t\t return; } } } void innerSetException(Throwable t) {\t for (;;) {\t\tint s = getState();\t\tif (s == RAN)\t\t return; if (s == CANCELLED) { releaseShared(0); return; }\t\tif (compareAndSetState(s, RAN)) { exception = t; result = null; releaseShared(0); done();\t\t return; }\t } } boolean innerCancel(boolean mayInterruptIfRunning) {\t for (;;) {\t\tint s = getState();\t\tif (ranOrCancelled(s))\t\t return false;\t\tif (compareAndSetState(s, CANCELLED))\t\t break;\t } if (mayInterruptIfRunning) { Thread r = runner; if (r != null) r.interrupt(); } releaseShared(0); done(); return true; } void innerRun() { if (!compareAndSetState(0, RUNNING)) return; try { runner = Thread.currentThread(); if (getState() == RUNNING) // recheck after setting thread innerSet(callable.call()); else releaseShared(0); // cancel } catch (Throwable ex) { innerSetException(ex); } } boolean innerRunAndReset() { if (!compareAndSetState(0, RUNNING)) return false; try { runner = Thread.currentThread(); if (getState() == RUNNING) callable.call(); // don\u0026#39;t set result runner = null; return compareAndSetState(RUNNING, 0); } catch (Throwable ex) { innerSetException(ex); return false; } } }}
推荐阅读
- dart这编程语言现在发展怎么样了,语法与Java,c#很相似,甚至更简洁
- Java工程师和C++工程师在工作上有啥区别哪个更适合自身发展
- 27岁,转行java的血与泪,该何去何从
- 怎样统计工程中未使用的java类
- 新互联网网站用Java还靠谱么对比Php,Python,Ruby的话
- 我想学java和安卓软件开发?
- 学计算机专业,java那些和网站开发选台式还是笔记本好
- JAVA设计思路
- 本人大专毕业一年,想要去培训,定了JAVAEE和安卓两个方向,应该学那个纠结,求帮助
- 咋防止低中奖概率的抽奖接口不被暴力请求
