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


  • 摘要:Future模式類似於js中的ajax等,是一個異步獲取數據的機制,這里我把自己的一些形象理解通過代碼實現了一下。該機制可以形象的理解為:調用獲取數據的方法,首先獲得一個沒有裝數據的空箱子(這個箱子有獲取數據和裝載數據的機制),至於箱子中的數據是通過另開一個線程去獲取的,隔一段時間之后,當我們想要獲取箱子中的數據的時候,就直接從箱子中拿就行了,一般情況下,由於獲取到箱子之后到我需要從箱子中拿取數據應該已經過了一段時間(因為做其他一些操作),正是這一段時間,數據通過其它線程已經
  • 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();
    }

from: https://www.aliyun.com/jiaocheng/1337978.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM