多线程手写Future模式

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("==========");

    }

}

在调用的时候,就可以看到我们想要的效果,阻塞方式的话,会把主线程阻塞掉,非阻塞方式的话,不会当前进程会等的回调之后停止.

 

posted @ 2019-04-26 15:44  北京de小刀  阅读(722)  评论(0编辑  收藏  举报