■ Future パターン
* 将来実行できる状態になるまで待つ * 処理の実行担当者は、処理が渡されると別スレッド上で処理を開始して、 メインスレッドには即座にFutureオブジェクトを返すこと * 現在はまだ結果を取得できないが、将来のある時点で取得することになる
補足:JavaScript/TypeScriptの場合
* JavaScript/TypeScriptの場合、Promiseオブジェクトに当たる。
非同期処理 ~ async/await, Promise ~
https://dk521123.hatenablog.com/entry/2021/01/16/202822
■ サンプル
http://www.hyuki.com/dp/dpinfo.html#Future
を参考に、Future パターンを理解するためのプログラムを組む。 (実際には、java.util.concurrent を使った方がいいらしいので、あくまで理解のため)
IDrawing.java
// インターフェイスを用意する public interface IDrawing { public abstract void draw(String content); }
FutureDrawer.java
// 用意したインターフェイスを継承する
public class FutureDrawer implements IDrawing {
private IDrawing drawer;
public synchronized void draw(String content) {
while (this.drawer == null) {
try {
System.out.println("\tIn FutureDrawer: wait");
wait();
} catch (InterruptedException e) {
}
}
System.out.println("\tIn FutureDrawer : drawing start.");
this.drawer.draw(content);
}
public synchronized void setPrinter(IDrawing drawer) {
this.drawer = drawer;
notifyAll();
}
}
RealDrawer.java
// 用意したインターフェイスをこっちも継承する public class RealDrawer implements IDrawing { public void draw(String content) { System.out.println("\tRealDrawer draws \"" + content + "\""); } }
DrawManager.java
import java.util.Random; public class DrawManager extends Thread { private FutureDrawer drawer; public DrawManager() { this.drawer = new FutureDrawer(); } public void run() { System.out.println(Thread.currentThread().getName() + " is sleeping."); try { this.doHeavyJob(); } catch (InterruptedException e) { } System.out.println(Thread.currentThread().getName() + " sets a RealDrawera."); this.drawer.setPrinter(new RealDrawer()); } public void requestDrawing(String content) { this.drawer.draw(content); } private void doHeavyJob() throws InterruptedException { Random random = new Random(); Thread.sleep(random.nextInt(10000)); } }
Main.java
public class Main {
public static void main(String[] args) {
DrawManager drawManager = new DrawManager();
drawManager.start();
System.out.println(
Thread.currentThread().getName() + " is drawing...");
drawManager.requestDrawing("Hello Mike [1].");
drawManager.requestDrawing("Hello Tom [2].");
drawManager.requestDrawing("Hello World [3].");
}
}
出力
Thread-0 is sleeping.
main is drawing...
In FutureDrawer: wait
Thread-0 sets a RealDrawera.
In FutureDrawer : drawing start.
RealDrawer draws "Hello Mike [1]."
In FutureDrawer : drawing start.
RealDrawer draws "Hello Tom [2]."
In FutureDrawer : drawing start.
RealDrawer draws "Hello World [3]."
■ 補足
* Future インターフェースがJava標準で用意されている
http://www.techscore.com/tech/Java/JavaSE/Thread/8-3/
参考文献
http://www.hyuki.com/dp/dpinfo.html#Future
http://team-pag.interprism.co.jp/member/okazawa/blog/?p=704
関連記事
非同期処理 ~ async/await, Promise ~
https://dk521123.hatenablog.com/entry/2021/01/16/202822
Python ~ 非同期 / concurrent.futures ~
https://dk521123.hatenablog.com/entry/2023/04/19/232949
Scala ~ 非同期 / Future ~
https://dk521123.hatenablog.com/entry/2023/04/30/000000