多线程之Future模式
Posted gdpuzxs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程之Future模式相关的知识,希望对你有一定的参考价值。
对于多线程,当A线程需要获得B线程的处理结果,而B线程处理业务需要很长时间,这时候A线程如果一直等待B线程的处理结果,线程A才能继续往下执行代码,这种方式在效率不是很好。所以,这种场景可以使用多线程的Future模式。
Future模式,就是当A线程需要B线程的处理结果,启动B线程,然后A线程继续往下走,而不必一直等待B线程的结果,当A线程需要用到B线程的结果时候再去获取结果,如果B线程还没处理好业务逻辑,则A线程一直处于阻塞状态。直到B线程处理完成。下面总结一下Future模式的实现方式。
首先客户端向服务器请求,但是这个资源的创建是非常耗时的,这种情况下,首先返回Client一个FutureSubject,以满足客户端的需求,同时,Future会通过另外一个Thread 去构造一个真正的资源,资源准备完毕之后,在给future一个通知。如果客户端急于获取这个真正的资源,那么就会阻塞客户端的其他所有线程,等待资源准备完毕。
公共数据接口,FutureData和RealData都要实现
public interface Data { public abstract String getConent(); }
public class FutureData implements Data{ private RealData realData; private boolean isReady=false;
//进行真实数据的装载 public synchronized void setRealData(RealData realData){ if(isReady) return; isReady=true; this.realData=realData; notify(); } //如果业务还没处理完成,则进入阻塞状态 public synchronized String getConent() { while(!isReady){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
//业务逻辑处理完成,直接返回真实结果 return this.realData.getConent(); } }
public class RealData implements Data{ private String result; //真正处理业务逻辑的方法 public RealData(String queryStr){ System.out.println("这是一个很耗时的请求..."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("操作完毕,获取结果"); result="查询结果"; } public String getConent() { return result; } }
public class FutureClient { //处理客户端的请求 public Data request(final String queryStr){
final FutureData futureDate =new FutureData();
//开启一个新的线程去处理复杂的业务逻辑 new Thread(new Runnable() { public void run() { RealData realData=new RealData(queryStr);
//处理完成对数据进行装载 futureDate.setRealData(realData); } }).start();
//返回给客户端 return futureDate; } }
public class TestFuture { public static void main(String[]args){ FutureClient fc=new FutureClient(); Data data=fc.request("查询条件.."); System.out.println("请求发送成功!"); System.out.println("做其他的事情..."); String result = data.getConent(); System.out.println(result); } }
在JDK1.5 Concurrent 中,提供了这种Callable和Future。Callable产生结果,Future拿到结果。 代码如下:
public class Task implements Callable<String> { public String call() throws Exception { Thread.sleep(5000); return "Hello Future"; } }
首先处理业务逻辑的类必须实现Callable接口,他与runable接口的区别是,runable接口重写的Run方法没有返回值,而Callable接口可以定义返回值。
public class FutureDemo { public static void main(String[]args) throws InterruptedException, ExecutionException{ System.out.println("已经提交资源申请"); ExecutorService executor=Executors.newCachedThreadPool(); Task task =new Task(); Future<String> future=executor.submit(task); System.out.println("继续做其他事情..."); if(!future.isDone()){ System.out.println("任务还没处理完成.."); } System.out.println("获取返回结果:"+future.get()); if(future.isDone()){ System.out.println("任务处理完成"); } executor.shutdown(); } }
使用线程池 ExecutorService executor=Executors.newCachedThreadPool(),调用submit方法开启线程,submit方法与executor方法的区别是,submit可以传入实现Callable或者runable接口类型的参数,而executor只可以传入实现runable接口类型的参数。
以上是关于多线程之Future模式的主要内容,如果未能解决你的问题,请参考以下文章