future模式
在进行耗时操作的时候,线程直接阻塞,我们需要优化这样的代码,让他再启动一个线程,不阻塞.可以执行下面的代码. 这个时候我们就用到了未来者模式
future设计类
只有一个方法
public interface Future<T> { T get() throws InterruptedException; }
futureTask 类
public interface FutureTask<T> { T call(); }
asyncFuture 类是fufure的实现类
/** * @Created by xiaodao */ public class AsynFuture<T> implements Future<T> { private volatile boolean done = true; private T result; public void done(T result){ synchronized (this){ this.result= result; this.done=false; this.notifyAll(); } } @Override public T get() throws InterruptedException { synchronized (this){ while (done){ this.wait(); } } return result; } }
FutureService
讲 fufure类 和futuretask类连接起来
public class FutureService { public <T> Future<T> subimt(final FutureTask<T> task){ AsynFuture<T> asynFuture= new AsynFuture(); new Thread(()->{ T result = task.call(); asynFuture.done(result); }).start(); return asynFuture; } public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) { AsynFuture<T> asynFuture = new AsynFuture<>(); new Thread(() -> { T result = task.call(); asynFuture.done(result); consumer.accept(result); }).start(); return asynFuture; } }
里面有俩种方法,一种是调用get的时候会阻塞,一种通过callable的方式回调回来,这样更加合理
提供一个测试了类
/** * Future ->代表的是未来的一个凭据 * FutureTask ->将你的调用逻辑进行了隔离 * FutureService ->桥接 Future和 FutureTask */ public class SyncInvoker { public static void main(String[] args) throws InterruptedException { /** * 这种方式在调用的时候被阻塞住了.不好 */ FutureService futureService = new FutureService(); Future<String> future = futureService.subimt(() -> { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } return "FINISH"; }); /** * 不阻塞 */ futureService.submit(() -> { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return "FINISH-callable"; },System.out::println); System.out.println(future.get()); System.out.println("other thing ......."); Thread.sleep(1000); System.out.println("=========="); } }
在调用的时候,就可以看到我们想要的效果,阻塞方式的话,会把主线程阻塞掉,非阻塞方式的话,不会当前进程会等的回调之后停止.