Java多線程基礎(十一)——Future模式

1、定義

Future模式用來獲取線程的執行結果。在Thread-Per-Message模式中,若是調用一個線程異步執行任務,沒有辦法獲取到返回值,就像:
host.request(10,'A');
而Future模式送出請求後,立刻就要獲取返回值,就像:
Data data=host.request(10,'A');
可是上述的返回值並非程序的執行結果,由於線程是異步的,主線程調用該該方法時,異步線程可能纔剛剛啓動。須要一段時間後像下面這樣獲取執行結果:
data.getContent();異步

2、模式案例

Data接口/實現:this

public interface Data {
    public abstract String getContent();
}
public class RealData implements Data {
    private final String content;
    public RealData(int count, char c) {
        System.out.println("        making RealData(" + count + ", " + c + ") BEGIN");
        char[] buffer = new char[count];
        for (int i = 0; i < count; i++) {
            buffer[i] = c;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("        making RealData(" + count + ", " + c + ") END");
        this.content = new String(buffer);
    }
    public String getContent() {
        return content;
    }
}
public class FutureData implements Data {
    private RealData realdata = null;
    private boolean ready = false;
    public synchronized void setRealData(RealData realdata) {
        if (ready) {
            return;
        }
        this.realdata = realdata;
        this.ready = true;
        notifyAll();
    }
    public synchronized String getContent() {
        while (!ready) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        return realdata.getContent();
    }
}

Host類:spa

public class Host {
    public Data request(final int count, final char c) {
        System.out.println("    request(" + count + ", " + c + ") BEGIN");
        final FutureData future = new FutureData();
        new Thread() {
            public void run() {
                RealData realdata = new RealData(count, c);
                future.setRealData(realdata);
            }
        }.start();
        System.out.println("    request(" + count + ", " + c + ") END");
        return future;
    }
}

執行:線程

public class Main {
    public static void main(String[] args) {
        System.out.println("main BEGIN");
        Host host = new Host();
        Data data1 = host.request(10, 'A');
        Data data2 = host.request(20, 'B');
        Data data3 = host.request(30, 'C');
 
        System.out.println("main otherJob BEGIN");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("main otherJob END");
        System.out.println("data1 = " + data1.getContent());
        System.out.println("data2 = " + data2.getContent());
        System.out.println("data3 = " + data3.getContent());
        System.out.println("main END");
    }
}

3、模式講解

Future模式的角色以下:code

  • Client(委託人)參與者

Client參與者會向Host參與者送出請求(request),Client參與者會立刻獲得VirtualData,做爲請求結果的返回值。(案例中的Main類就是Client)對象

  • Host參與者

Host參與者接受請求(request),而後建立線程進行異步處理。Host參與者會當即返回Future(以VirturalData的形式)。blog

  • VirtualData(虛擬數據)參與者

VirtualData是用來統一表明Future參與者與RealData參與者。(案例中Data接口就是VirtualData參與者)接口

  • RealData(實際數據)參與者

RealData表示實際的數據。rem

  • Future參與者

Future參與者包含獲取實際的數據和設置實際數據的方法。Host類會建立該對象,當異步線程處理完成時,會調用Future的設置數據的方法。get

相關文章
相關標籤/搜索