上篇博文带大家解析了future的原理,没看请走直通车https://blog.csdn.net/qq_32459653/article/details/81558342
总的来说future的原理是,其他线程在获取的是否检查任务是否完成,完成了我们直接返回,没完成我们就阻塞,等到完成后再唤醒所有线程,这个是根本思想,已经这个这个思想,我们实现一个自己的futureTask,并且,我们这个futuretask还带有监听器,能够在完成之后通知给我们感兴趣的对象,代码我已经写出来了,相应大家有上一篇的基础肯定能很好的看懂,下面我就贴代码了
package com.MyFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * @author zoujianglin * @date 2018/8/10 15:42 * V 为执行结果的类型参数 * 该future 参考netty的实现 改良原future, * 返回一个带监听器的future,完成之后可做相关工作 */ public interface IFuture<V> extends Future<V> { boolean isSuccess(); //判断是否成功 V getNow(); //获取值 Throwable cause(); //获取异常 boolean isCancellable();//是否可以取消,一旦开始不能取消 IFuture<V> await() throws InterruptedException; IFuture<V> awaitUninterruptibly(); IFuture<V> addListener(IFutureListener<V> listener); //添加监听器 IFuture<V> removeListener(IFutureListener<V> listener); //移除监听器 }
package com.MyFuture; import java.util.Collection; import java.util.concurrent.*; /** * @author zoujianglin * @date 2018/8/10 15:51 */ public abstract class AbstractFuture<V> implements IFuture<V>, Callable<V> { private volatile Object result;//保证多线程的可见性; /** * 监听器集合 */ protected Collection<IFutureListener<V>> listeners = new CopyOnWriteArrayList<IFutureListener<V>>(); private static final SuccessSignal SUCCESS_SIGNAL = new SuccessSignal(); @Override public boolean isSuccess() { return result == null ? false : !(result instanceof CauseHolder); } @Override public V getNow() { return (V) (result.equals(SUCCESS_SIGNAL) ? null : result); } @Override public Throwable cause() { if (result != null && result instanceof CauseHolder) { return ((CauseHolder) result).cause; } return null; } @Override public boolean isCancellable() { return false; } @Override public IFuture<V> await() throws InterruptedException { return await0(true); } private IFuture<V> await0(boolean interruptable) throws InterruptedException { if (!isDone()) { //已完成直接返回 //若允许中断且被中断打断,而抛出异常 if (interruptable && Thread.interrupted()) { throw new InterruptedException("thread" + Thread.currentThread() + "has beeb interrupted"); } boolean interrupted = false; synchronized (this) { while ( !isDone()) { try { wait();//线程等待 } catch (InterruptedException e) { if (interruptable) { throw e; } else { interrupted = true; } } } } if (interrupted) { //设标志位的原因是,应为wait返回后,标志位会被clear //重新设置标志位 Thread.currentThread().interrupt(); } } return this; } @Override public IFuture<V> awaitUninterruptibly() { try { return await0(false); } catch (InterruptedException e) { throw new java.lang.InternalError(); } } /** * 添加监听器 * * @param listener * @return */ @Override public IFuture<V> addListener(IFutureListener<V> listener) { if (listener == null) { throw new NullPointerException("listener not null"); } if (isDone()) { notifyListener(listener); return this; } synchronized (this) { if (!isDone()) { //没完成加入 listeners.add(listener); return this; } } notifyListener(listener); //到达这里说明已经完成 return this; } /** * 移除监听器, * * @param listener * @return */ @Override public IFuture<V> removeListener(IFutureListener<V> listener) { if (listener == null) { throw new NullPointerException("listener not null"); } if (!isDone()) { listeners.remove(listener); } return this; } @Override public boolean cancel(boolean mayInterruptIfRunning) { if (isDone()) { //完成不能取消 return false; } synchronized (this) { if (isDone()) { //加锁在判断一次 return false; } result = new RuntimeException("主动取消"); notifyAll(); //唤醒所有等待的对象 } //这里通知监听器; notifyListeners(); return true; } @Override public boolean isCancelled() { return result != null && result instanceof CauseHolder && ((CauseHolder) result).cause instanceof CancellationException; } /** * 该方法用来判断是否完成 * * @return */ @Override public boolean isDone() { return result != null; } @Override public V get() throws InterruptedException, ExecutionException { await();//等待异步结果 Throwable cause = cause(); if (cause == null) { //没发生异常正常返回 return getNow(); } if (cause instanceof CancellationException) { throw (CancellationException) cause; //被取消了 } throw new ExecutionException(cause);//其他异常 } @Override public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return null; } protected void notifyListeners() { for (IFutureListener<V> listener : listeners) { notifyListener(listener); } } protected void notifyListener(IFutureListener listener) { listener.operationCompleted(this); } protected IFuture<V> setFailure(Throwable cause) { if (setFailure0(cause)) { notifyListeners(); return this; } throw new IllegalStateException("complete already:" + this); } private boolean setFailure0(Throwable cause) { if (isDone()) { return false; } synchronized (this) { if (isDone()) { return false; } result = new CauseHolder(cause); notifyAll(); } return true; } protected IFuture<V> setSuccess(Object result) { if (setSuccess0(result)) { notifyListeners(); return this; } throw new IllegalStateException("complete already:" + this); } private boolean setSuccess0(Object result) { if (isDone()) { return false; } synchronized (this) { if (isDone()) { return false; } if (result == null) {//正常结束,返回值为空 this.result = SUCCESS_SIGNAL; } else { this.result = result; } notifyAll(); } return true; } private static class SuccessSignal { } private static final class CauseHolder { final Throwable cause; CauseHolder(Throwable cause) { this.cause = cause; } } }
//监听器接口由用户自己实现
package com.MyFuture; /** * @author zoujianglin * @date 2018/8/10 15:53 */ public interface IFutureListener<V> { void operationCompleted(IFuture iFuture); }
** * 该被适合被子类继承使用,并且必须覆盖他的call 方法 * 以此来实现一个带返回值的Runnable * * @param <V> */ public abstract class MyFutureTask<V> extends AbstractFuture<V> implements Runnable { @Override public void run() { try { V t = call(); setSuccess(t); } catch (Exception e) { setFailure(e); } } /** * 留给子类覆盖 * * @return * @throws Exception */ @Override public abstract V call() throws Exception; }
下面是测试 我们只需继承MyFutureTask,实现它的call方法即可,测试类如下,感兴趣的可以一步一步debug看看如何实现的
package com.MyFuture; /** * @author zoujianglin * @date 2018/8/10 16:47 */ public class TestMyFutureTask extends MyFutureTask<Integer> { public static void main(String[] args) { final TestMyFutureTask testMyFutureTask = new TestMyFutureTask(); testMyFutureTask.addListener(new IFutureListener<Integer>() { @Override public void operationCompleted(IFuture iFuture) { System.out.println("完成了"); } }); Thread thread1 = new Thread(testMyFutureTask); thread1.setName("excutor"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { int t = testMyFutureTask.get(); System.out.println(t); } catch (Exception e) { e.printStackTrace(); } } }); thread2.setName("get2"); Thread thread3 = new Thread(new Runnable() { @Override public void run() { try { int t = testMyFutureTask.get(); System.out.println(t); } catch (Exception e) { e.printStackTrace(); } } }); thread3.setName("get3"); thread1.start(); thread2.start(); thread3.start(); } @Override public java.lang.Integer call() throws Exception { int a = 1; int b = 3; Thread.sleep(100); return a + b; } }