本文共 3001 字,大约阅读时间需要 10 分钟。
/** * Future模式:是并行模式属于设计优化的一部分,是对一些常用的多线程结构的总结和抽象。 * 与串行程序相比,并行程序的结构通常更为复杂,因此合理的使用并行模式在多线程开发中更具有意义。 * 这个模式类似在发送ajax请求,页面是异步的进行后台处理,用户无须一直等待结构就可以继续浏览和进行其他操作。 */ public class C03Future { public static void main(String[] args) throws InterruptedException { Client client = new Client(); String data = client.getData("123"); System.out.println(data); } } class Client {
public String getData(String query) throws InterruptedException { //获取到代理对象 ProxyData proxyData = new ProxyData();
//偷偷起个线程去加载数据 new Thread(new Runnable() { @Override public void run() { System.out.println("开始加载数据"); HandlerData handlerData = null; try { handlerData = new HandlerData(query);
//设置加载好的数据给代理对象 System.out.println("数据加载完成"); proxyData.setHandlerData(handlerData); } catch (InterruptedException e) { e.printStackTrace(); } } }).start();
System.out.println("返回代理对象");
return proxyData.getHandlerData(); }
} /** * 数据代理 */ class ProxyData {
private HandlerData handlerData;
private boolean isReady = false;
/** * 设置数据,如果数据已有就直接返回,没有数据就进行处理。 * 假设:数据处理过程需要耗时N秒,用户在get时,就节省了部分过程的时间。 */ public synchronized void setHandlerData(HandlerData handlerData) { //数据已经准备好了,直接返回 if (isReady) { System.out.println(isReady + ":数据未准备好"); return ; } //数据没有准备好,开始进行数据处理 this.handlerData = handlerData; isReady = true;
System.out.println("代理对象设置数据成功,唤醒getHandlerData的等待。"); //唤醒通知 notify(); }
/** * 获取数据 */ public synchronized String getHandlerData() throws InterruptedException { //如果数据没有处理好,则等待处理 while (!isReady) { System.out.println(isReady + ":数据未准备好,getHandlerData 进入等待"); wait(); }
//返回装好的数据 return this.handlerData.getResult(); } } /** * 真实的数据 */ class HandlerData { /** * 数据结果 */ private String result;
/** * 模拟数据处理过程 */ public HandlerData(String query) throws InterruptedException { System.out.println("模拟-数据查询");
//数据处理 Thread.sleep(5000);
System.out.println("模拟-数据处理完成"); result = "end"; }
public String getResult() { return result; } } |
public class C03Future01 { public static void main(String[] args) throws InterruptedException, ExecutionException {
//JDK自带Api ========================================== String query = "select * from user;";
//构建FutureTask,并且传入需要真正进行业务处理和实现了Callable接口的类 FutureTask<String> futureTask1 = new FutureTask<String>(new FutureTestClass(query)); FutureTask<String> futureTask2 = new FutureTask<String>(new FutureTestClass(query));
//创建一个固定线程的线程池 ExecutorService pool = Executors.newFixedThreadPool(1);
//提交任务,则开启线程执行call方法 //submit()和execute()方法的区别,可以看线程池篇的文章 Future submit1 = pool.submit(futureTask1); Future submit2 = pool.submit(futureTask2);
System.out.println("Main线程处理别的业务逻辑"); Thread.sleep(2000);
System.out.println(futureTask1.get()); System.out.println(futureTask2.get());
pool.shutdown(); } } /** * 必须要实现Callable接口 */ class FutureTestClass implements Callable<String> {
private String query;
public FutureTestClass(String query) { super(); this.query = query; }
@Override public String call() throws Exception { Thread.sleep(3000); String result = query + ":处理完成"; return result; } } |
转载地址:http://kmmxi.baihongyu.com/