小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Java多線程編程中Future模式的詳解

 quasiceo 2018-09-09

1. Future模式核心思想

Future模式的核心在于:去除了主函數(shù)的等待時間,并使得原本需要等待的時間段可以用于處理其他業(yè)務邏輯(根據(jù)《Java程序性能優(yōu)化》)。

Future模式有點類似于商品訂單。在網(wǎng)上購物時,提交訂單后,在收貨的這段時間里無需一直在家里等候,可以先干別的事情。類推到程序設計中時,當提交請求時,期望得到答復時,如果這個答復可能很慢。傳統(tǒng)的時一直等待到這個答復收到時再去做別的事情,但如果利用Future設計模式就無需等待答復的到來,在等待答復的過程中可以干其他事情。

例如如下的請求調用過程時序圖。當call請求發(fā)出時,需要很長的時間才能返回。左邊的圖需要一直等待,等返回數(shù)據(jù)后才能繼續(xù)其他操作;而右邊的Future模式的圖中客戶端則無需等到可以做其他的事情。服務器段接收到請求后立即返回結果給客戶端,這個結果并不是真實的結果(是虛擬的結果),也就是先獲得一個假數(shù)據(jù),然后執(zhí)行其他操作。

\


2. Future模式Java實現(xiàn)

Client的實現(xiàn)

Client主要完成的功能包括:1. 返回一個FutureData;2.開啟一個線程用于構造RealData。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Client {
    public Data request(final String string) {
        final FutureData futureData = new FutureData();
         
        new Thread(new Runnable() {
            @Override
            public void run() {
                //RealData的構建很慢,所以放在單獨的線程中運行
                RealData realData = new RealData(string);
                futureData.setRealData(realData);
            }
        }).start();
         
        return futureData; //先直接返回FutureData
    }
}
Data的實現(xiàn)

無論是FutureData還是RealData都實現(xiàn)該接口。

1
2
3
public interface Data {
    String getResult() throws InterruptedException;
}
FutureData的實現(xiàn)

FutureData是Future模式的關鍵,它實際上是真實數(shù)據(jù)RealData的代理,封裝了獲取RealData的等待過程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//FutureData是Future模式的關鍵,它實際上是真實數(shù)據(jù)RealData的代理,封裝了獲取RealData的等待過程
public class FutureData implements Data {
    RealData realData = null; //FutureData是RealData的封裝
    boolean isReady = false//是否已經(jīng)準備好
     
    public synchronized void setRealData(RealData realData) {
        if(isReady)
            return;
        this.realData = realData;
        isReady = true;
        notifyAll(); //RealData已經(jīng)被注入到FutureData中了,通知getResult()方法
    }
    @Override
    public synchronized String getResult() throws InterruptedException {
        if(!isReady) {
            wait(); //一直等到RealData注入到FutureData中
        }
        return realData.getResult();
    }
}
RealData的實現(xiàn)

RealData是最終需要使用的數(shù)據(jù),它的構造函數(shù)很慢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class RealData implements Data {
    protected String data;
    public RealData(String data) {
        //利用sleep方法來表示RealData構造過程是非常緩慢的
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.data = data;
    }
    @Override
    public String getResult() {
        return data;
    }
}
測試運行

主函數(shù)主要負責調用Client發(fā)起請求,并使用返回的數(shù)據(jù)。

1
2
3
4
5
6
7
8
9
10
11
12
public class Application {
    public static void main(String[] args) throws InterruptedException {
        Client client = new Client();
        //這里會立即返回,因為獲取的是FutureData,而非RealData
        Data data = client.request("name");
        //這里可以用一個sleep代替對其他業(yè)務邏輯的處理
        //在處理這些業(yè)務邏輯過程中,RealData也正在創(chuàng)建,從而充分了利用等待時間
        Thread.sleep(2000);
        //使用真實數(shù)據(jù)
        System.out.println("數(shù)據(jù)="+data.getResult());
    }
}

3. Future模式的JDK內置實現(xiàn)

由于Future是非常常用的多線程設計模式,因此在JDK中內置了Future模式的實現(xiàn)。這些類在java.util.concurrent包里面。其中最為重要的是FutureTask類,它實現(xiàn)了Runnable接口,作為單獨的線程運行。在其run()方法中,通過Sync內部類調用Callable接口,并維護Callable接口的返回對象。當使用FutureTask.get()方法時,將返回Callable接口的返回對象。同樣,針對上述的實例,如果使用JDK自帶的實現(xiàn),則需要作如下調整。

首先,Data接口和FutureData就不需要了,JDK幫我們實現(xiàn)了。

其次,RealData改為這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.concurrent.Callable;
public class RealData implements Callable<string> {
    protected String data;
    public RealData(String data) {
        this.data = data;
    }
    @Override
    public String call() throws Exception {
        //利用sleep方法來表示真是業(yè)務是非常緩慢的
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return data;
    }
}</string>
最后,在測試運行時,這樣調用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Application {
    public static void main(String[] args) throws Exception {
        FutureTask<string> futureTask =
                new FutureTask<string>(new RealData("name"));
        ExecutorService executor =
                Executors.newFixedThreadPool(1); //使用線程池
        //執(zhí)行FutureTask,相當于上例中的client.request("name")發(fā)送請求
        executor.submit(futureTask);
        //這里可以用一個sleep代替對其他業(yè)務邏輯的處理
        //在處理這些業(yè)務邏輯過程中,RealData也正在創(chuàng)建,從而充分了利用等待時間
        Thread.sleep(2000);
        //使用真實數(shù)據(jù)
        //如果call()沒有執(zhí)行完成依然會等待
        System.out.println("數(shù)據(jù)=" + futureTask.get());
    }
}</string></string>

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多