併發編程:Future模式

一、Future模式

Futrue模式:對於多線程,如果線程A要等待線程B的結果,那麼線程A沒必要等待B,直到B有結果,可以先拿到一個未來的Future,等B有結果是再取真實的結果。

二、Future模式Demo

公共的數據接口,真實數據和未來數據都要實現該接口

package ConcurrentProgramming.middle.part3.Future;

/**
 * @Author: zdj
 * @Description: 公共數據接口 FutureData 和 RealData都要實現
 * @Date: 2019年03月14日 14:54
 */
public interface Data {
    String getRequest();
}

FutureData,未來數據。客戶端發出請求時,直接響應該對象,通知客戶端請求已經接受到,正在處理。

package ConcurrentProgramming.middle.part3.Future;

import javax.annotation.Resource;

/**
 * @Author: zdj
 * @Description: 未來數據,客戶端發出請求時,直接響應該對象,通知客戶端請求已經接受到,正在處理。
 * @Date: 2019年03月14日 14:55
 */
public class FutureData implements Data {

    private RealData realData;

    /**
     * 用來判斷數據是否準備完畢
     */
    private boolean ready = false;

    public synchronized void setRealData(RealData realData) {
        //如果數據準備完畢直接返回
        if (ready) {
            return;
        }
        //數據未準備,則裝載數據
        this.realData = realData;
        ready = true;
        //喚醒阻塞線程
        notify();
    }

    public synchronized String getRequest() {
        //沒有準備好數據,阻塞
        if (!ready){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //準備好直接返回
        return this.realData.getRequest();
    }
}

真實數據,客戶端發出請求後,FutureData未來數據要加載的數據

package ConcurrentProgramming.middle.part3.Future;

/**
 * @Author: zdj
 * @Description: 真實數據,客戶端發出請求後,FutureData未來數據要加載的數據
 * @Date: 2019年03月14日 14:57
 */
public class RealData implements Data {

    private String result;

    public RealData(String queryStr){
        System.out.println("根據" + queryStr + "進行查詢,這是一個很耗時的操作..");
        try {
            Thread.sleep(5000);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("操作完畢,獲取結果。。。");
        result = "結果來了";
    }

    public String getRequest() {
        return result;
    }
}

客戶端

package ConcurrentProgramming.middle.part3.Future;

/**
 * @Author: zdj
 * @Description: 客戶端
 * @Date: 2019年03月14日 15:27
 */
public class FutureClient {
    public Data request(final String queryStr){
        //1、先返回一個空的數據給客戶端,告訴客戶端請求已經收到,正在獲取數據
        final FutureData futureData = new FutureData();
        //2、啓動一個新的線程,去加載真實的數據,獲取完畢後,將真實數據返回給客戶端
        new Thread(new Runnable() {
            public void run() {
                RealData realData = new RealData(queryStr);
                futureData.setRealData(realData);
            }
        }).start();
        //先返回FutureData,異步加載真實數據
        return futureData;
    }

}

測試Main

package ConcurrentProgramming.middle.part3.Future;

/**
 * @Author: zdj
 * @Description: Future模式 先返回給客戶端一個空的數據,告訴客戶端請求收到,
 *               異步去加載真實數據。當客戶端真正使用數據的時候,返回給客戶端真實數據
 *               此時如果數據沒有加載完畢,則會阻塞線程,直至數據加載完畢。
 * @Date: 2019年03月14日 15:31
 */
public class Main {
    public static void main(String[] args) {
        FutureClient futureClient = new FutureClient();
        Data data = futureClient.request("請求參數");
        System.out.println("請求發送成功!");
        System.out.println("做其他的事情...");

        String result = data.getRequest();
        System.out.println(result);
    }
}

運行結果

參考鏈接:https://www.cnblogs.com/plxx/p/4574141.html

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章