文章目录
菜鸟的一个学习笔记,欢迎大神 批评指正。
Java多线程相关知识【14】–设计模式–未来者模式(future)
1.问题的引入
当获取数据时,会出现获取数据的时间很长,从而占用了主程序的运行时间,然而,在获取数据后,可能下面的很多操作都与获取的内容无关,那么怎样才能解决相关的问题呢?
2.解决的方法
在出现前面介绍的情况时,我们可以使用异步实现来解决相应问题,即可以在处理完成一定的事情后,在来回调相应的结果,保证线程不被阻塞。
3.代码的实现
获取的结果
/**
* 获取的结果
* @param <T>
*/
public interface Future<T> {
T get () throws InterruptedException;
}
获取的结果的实现
/**
* 实现获取真正的结果
*
* @param <T>
*/
public class FutureAsyn<T> implements Future<T> {
private volatile boolean done = false;
private T result;
public void done(T result) {
synchronized (this) {
this.result = result;
this.done = true;
this.notifyAll();
}
}
@Override
public T get() throws InterruptedException {
synchronized (this) {
while (!done) {
this.wait();
}
}
return result;
}
}
要执行的任务
/**
* 要执行的任务
*
* @param <T>
*/
@FunctionalInterface
public interface FutureWork<T> {
T call();
}
任务的调度
/**
* 进行实际任务调度
*/
public class FutureService {
/**
* 进行任务的提交异步执行,做线程内容
* @param work 要做的任务
* @param <T> 任意的任务类型
* @return 得到的结果
*/
public <T> Future<T> submit(final FutureWork<T> work) {
FutureAsyn<T> asyn = new FutureAsyn<>();
new Thread(() -> {
T res = work.call();
asyn.done(res);
}).start();
return asyn;
}
}
使用方法
/**
* 进行相关的测试
*/
public class FutureClient {
public static void main(String[] args) throws InterruptedException {
FutureService futureService=new FutureService();
Future<String> res = futureService.submit(() -> {
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "ok";
});
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println(res.get());
}
}
4.问题的剖析
由于上述情况,若线程获取任务后,可能出现本线程工作完成后,获取的数据还未完全获取,而这时需要由两个进程来操作数据,从而造成浪费,那我们能否使用一个线程解决上述的要占用两个进程的问题呢
5.解决的方法
为任务操作完成后,添加任务的后续任务,即可实现相应的减少。
6.增强的代码的实现
获取的结果
/**
* 获取的结果
* @param <T>
*/
public interface Future<T> {
T get () throws InterruptedException;
}
获取的结果的实现
/**
* 实现获取真正的结果
*
* @param <T>
*/
public class FutureAsyn<T> implements Future<T> {
private volatile boolean done = false;
private T result;
public void done(T result) {
synchronized (this) {
this.result = result;
this.done = true;
this.notifyAll();
}
}
@Override
public T get() throws InterruptedException {
synchronized (this) {
while (!done) {
this.wait();
}
}
return result;
}
}
要执行的任务
/**
* 要执行的任务
*
* @param <T>
*/
@FunctionalInterface
public interface FutureWork<T> {
T call();
}
执行完要执行的任务后的任务
/**
* 实现任务完成后的操作(可使用java 8 的特性来实现)
* @see java.util.function.Consumer
* @param <T>
*/
@FunctionalInterface
public interface FutureWorkNext<T> {
void doing(T res);
}
任务的调度
/**
* 进行实际任务调度
*/
public class FutureService {
/**
* 升级 的异步回调,可在完成工作后自动执行任务,并可返回异步执行操作的结果
* @param work 要完成的任务
* @param nextWork 完成要完成的任务之后使用要完成的任务接下来进行的操作
* @param <T>
* @return
*/
public <T> Future<T> submit(final FutureWork<T> work, FutureWorkNext<T> nextWork) {
FutureAsyn<T> asyn = new FutureAsyn<>();
new Thread(() -> {
T res = work.call();
asyn.done(res);
nextWork.doing(res);
}).start();
return asyn;
}
}
使用方法
/**
* 进行相关的测试
*/
public class FutureClient {
public static void main(String[] args) throws InterruptedException {
FutureService futureService=new FutureService();
Future<String> res = futureService.submit(() -> {
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "ok";
},System.out::println);
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println("---------------------------------");
System.out.println("---------------------------------");
}
}