1. 程式人生 > >Java中的Future模式原理自定義實現

Java中的Future模式原理自定義實現

Future模式類似於js中的ajax等,是一個非同步獲取資料的機制,這裡我把自己的一些形象理解通過程式碼實現了一下。

該機制可以形象的理解為:呼叫獲取資料的方法,首先獲得一個沒有裝資料的空箱子(這個箱子有獲取資料和裝載資料的機制),至於箱子中的資料是通過另開一個執行緒去獲取的,隔一段時間之後,當我們想要獲取箱子中的資料的時候,就直接從箱子中拿就行了,一般情況下,由於獲取到箱子之後到我需要從箱子中拿取資料應該已經過了一段時間(因為做其他一些操作),正是這一段時間,資料通過其它執行緒已經被存放到箱子中了。

/**
 * 測試
 * @author yangcheng
 *
 */
public class MainTest {
	public static void main(String[] args){
		Client client=new Client();
		//拿到空箱子箱子
		FeatureCar result=(FeatureCar) client.requestData("這是我傳送的資料");
		System.out.println("繼續執行其他業務");
		//從空箱子中獲取資料 如果資料沒有則等待,一直等到拿到資料位置————因此 在獲取箱子中的資料之前可以做一些其它操作
		System.out.println(result.getResult());
	}

}

/**
 * 客戶端中,使用近似於javascript中的ajax的非同步請求資料的這種方式獲取資料
 * 
 * 該客戶端作用  需要構建非同步資料獲取的結構,以便讓main方法直接使用該類物件獲取其資料
 * 
 * @author yangcheng
 *
 */
public class Client {
	//
	public Data requestData(final String msg){
		//建立一個同步物件直接返回(盛放物品的箱子)
		final FeatureCar car=new FeatureCar();
		
		//建立一個執行緒 用於獲取資料(獲取箱子中的物品,這個物品是在把箱子已經交給請求者之後,慢慢放進箱子中的)
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				FeatureRealData realData=new FeatureRealData(msg);
				//把真實的資料放到箱子裡面
				car.setRealData(realData);
			}
		}).start();;
		//把箱子先返回給呼叫者  而裡面的資料是通過上面的執行緒非同步放進去的
		return car;
	}
}

/**
 * 箱子
 * 用於同步返回客戶端請求的資料(裝東西的“箱子”,剛剛返回給呼叫者時箱子是空的,裡面的資料是通過非同步執行緒獲取的)
 * 
 * @author yangcheng
 *
 */
public class FeatureCar implements Data{
	//組合一個真實資料物件
	private FeatureRealData realData;
	//這裡需要設定一個標識用於判斷realData物件中是否為null,如果為null的時候getResult方法被執行,就需要把getResult阻塞(wait())
	//預設沒有值
	private boolean flag=false;
	public synchronized void setRealData(FeatureRealData realData) {
		if(flag){
			try {
				//如果在非synchronized方法中呼叫方法 wait notify notifyAll  會報"java.lang.IllegalMonitorStateException"
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//預設setRealData方法可以直接執行 不會阻塞,
		flag=true;
		notify();
		this.realData = realData;
		
	}
	
	
	@Override
	public synchronized String getResult() {
		// TODO Auto-generated method stub
		while(true){
			if (!flag) {
				try {
					//當realData物件為null 執行緒等待
					System.err.println("**************************");
					wait();
					
				
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			notify();
			return realData.getResult();
		}
		
		
	}

}

/**
 * 被裝到箱子裡面的“物品”
 * 
 * 該類的作用就是  訪問資料庫  並將結果返回
 * @author yangcheng
 *
 */
public class FeatureRealData implements Data{
	private String resultData;
	
	//模擬訪問資料庫
	public	FeatureRealData(String msg){
		try {
			//模擬資料庫訪問花了3秒
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		resultData= "返回的真實資料:資料獲取成功!";
		
	}
	//將查詢結果返回
	@Override
	public String getResult() {
		// TODO Auto-generated method stub
		return resultData;
	}

}

/**
 * 該介面用於規範獲取資料的方法
 * @author yangcheng
 *
 */
public interface Data {
	public String getResult();
}