多线程手写Future模式

时间:2023-03-10 00:32:25
多线程手写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("=========="); } }

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