自己模拟实现Concurrent包下的Future模式

Future模式简介:在处理某些比较复杂的业务逻辑时,我们需要首先返回一个虚拟结果(即Future的含义),然后再Future中创建线程去执行其他的方法,如果这个虚拟的结果不会立即使用(比如在调用这个结果的某个方法前需要执行其他业务耗时操作),那么在执行真实结果的耗时会和其他业务耗时操作同时执行,从而节约了时间,这就是Future模式的出发点。

代码实现:

package thread.future模式;

public interface Data {
	public String getRequest();
}
简单接口,只有一个getRequest方法,以后我们的模拟结果类(FutureData)和真实结果类(RealData)都会实现这个接口

package thread.future模式;

public class RealData implements Data {

	
	public RealData() {
		System.out.println("缓慢初始化...");
		try {
			//模拟初始化复杂业务对象的时间
			Thread.sleep(5000);
			System.out.println("RealData初始化完毕");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public String getRequest() {
		String result = null;
		//模拟获得结果所需要的时间,这里将是以后最为复杂的业务逻辑部分
		try {
			Thread.sleep(6000);
			result = "结果查询完毕,并返回";
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return result;
	}

}
RealData类是我们要执行真实数据的类,其中getRequest是我们主要的业务方法,需要耗费一定的时间(初始化5秒,执行方法6秒)

package thread.future模式;




public class FutureData implements Data {


	private RealData realData;


	private boolean isReady = false;


	private Object lock = new Object();


	public void setRealData(RealData realData) {
		synchronized (lock) {
			if(isReady){
				return;
			}
			this.realData = realData;
			System.out.println("设置RealData已经成功");
			isReady = true;
			lock.notify();
		}
	}


	@Override
	public String getRequest() {
		synchronized (lock) {
			while(!isReady) {
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}


			return this.realData.getRequest();
		}


	}


}
FutureData类是我们的虚拟结果类,可以看到setRealDatat方法就是将参数中初始化成功的RealData对象设置到FutureData的一个成员变量中,并发出notify通知,同时设置flag为成功,getRequest方法在setRealData方法执行成功之前一直都会处于一个阻塞状态,直到接收到notify通知会调用RealData的getRequest方法返回真实数据

package thread.future模式;

public class FutureClient {

	public Data getData() {

		final FutureData futureData = new FutureData();

		new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("多线程启动...");
				RealData realData = new RealData();
				futureData.setRealData(realData);
			}
		}).start();

		return futureData;
	}

}
FutureClient简单的代理对象方法,作为主业务逻辑获取Data的伪代理对象,在其中启动一个线程调用真实数据方法的创建和业务数据计算,并赋给RealData,实际返回的是RealData对象

package thread.future模式;

public class Main {
	public static void main(String[] args) throws InterruptedException {
		long start = System.currentTimeMillis();
		FutureClient client = new FutureClient();
		Data d = client.getData();
		//模拟其他业务方法耗时
		Thread.sleep(5000);
		//使用data数据
		System.out.println(d.getRequest());
		long end = System.currentTimeMillis();
		System.out.println("总计耗时:" + (end-start) + "秒");
	}
}
模拟的调用方法,可以看到先执行了FutureClient的getData()方法,返回一个Data(实际上是一个虚拟对象)对象,实际上我们后台新创建一个线程获取真实数据对象并计算结果,同时,会执行本类中耗时的业务逻辑

执行结果

多线程启动...
缓慢初始化...
RealData初始化完毕
设置RealData已经成功
结果查询完毕,并返回
总计耗时:11003秒

业务总耗时(不使用多线程):RealData初始化5秒业务逻辑5秒,Main方法5秒总计16秒

使用这种设计模式总耗时:11秒

这样,在Controller层做实现时,就不必关心封装的代码到底是怎么写的,对某些业务场景有一定的适用性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值