こんばんは!木曜早朝のぱかぱかです!
昨日の夜寝落ちしてしまったので朝に書いています。
毎週水曜日は定時に上がれるのですが、せっかく時間がたくさんあるのに寝てしまってもったいないですね…
現在自作アプリでお天気APIを使用して現在の天気を表示する処理を実装しています。
Web連携にあたりどうしても登場するのが非同期処理。
実務でもよく登場しますが苦手とする内容の一つです…
お天気APIの記事をまとめる前に、Java Goldで学んだ並列処理についてまとめていきます。
非同期処理を実装する方法はいくつかありますが、今回はその中でもExecutorフレームワークを使用した並列処理についてまとめていきます。
◆Executorフレームワーク
Executorフレームワークを使うと、スレッドの再利用やスケジューリングを行うコードを簡単に実装できます。
通常Executorオブジェクトは明示的にスレッドを作成する代わりに使用できるのです。
以下にThreadを使うパターンとExecutorを使う場合の例を示します。
Runnableインターフェースを継承しrun()メソッドをオーバーライドしたものをRunnableTask()とします。
・スレッドを利用した実装(Runnableインターフェース)
RunnableTask()をThreadクラスのコンストラクタ引数に渡す。
その後start()メソッドを呼び出すとスレッドが開始する。
new Thread(new(RunnableTask())).start()
・Executorオブジェクトを利用した実装
execute()メソッドの引数にRunnableTask()を渡す。
※結果を取得するためには後述のsubmit()メソッドを使用する。
Executor executor = // Executorオブジェクト
Executor.execute(new RunnableTask())
◆Executorオブジェクトの取得方法
ここがExecutorのお手軽さのミソでしょうか?
Executorsクラスのメソッドを使用して、どのようなスレッドで処理するのかをしていすることができます。
例として以下のようなものがあり、それぞれ特徴が異なります。
・static ExecutorService newSingleThreadExecutor()
1つのスレッドでタスクの処理するExecutorServiceを返す。
・static ExecutorService newFixedThreadExecutor()
固定数のスレッドを再利用するスレッドプールを提供するExecutorServiceを返す。
・static ScheduledExecutorService newSingleThreadScheduledExecutor()
指定された遅延時間後、または周期的にコマンドの実行をスケジュールできる
1つのスレッドでタスクの処理するScheduledExecutorServiceを返す。
・static Callable<Object> callable(Runnable task)
呼び出し時に指定されたタスクを実行し、指定された結果を返すCallableオブジェクトを返す。
◆ExecutorServiceインターフェース
上に示したExecutorsメソッドの戻り値はExecutorServiceです。
これに対して処理の実行や終了を管理する以下のようなメソッドが用意されています。
・void shutdown()
順序正しくシャットダウンをする。
・<T> Future<T> submit(Callable<T> task)
値を返す実行用のCallableタスクを送信して結果を表すFutureオブジェクトを返す。
・Future<?> submit(Runnable task)
実行用のRunnableタスクを送信して結果を表すFutureオブジェクトを返す。
◆Futureオブジェクト
上記のsubmit()メソッドの戻り値であるFutureオブジェクトは、以下のメソッドによってタスク完了のチェック、タスク結果の取得などを行うことができます。
・boolean cancel(boolean mayInterruptIfRunning)
タスクの実行取り消しを試みる。
・V get(long timeout, TimeUnit unit)
指定された時間タスクが完了するまで待機し、タスク結果を取得する。
正常にタスクが完了した場合nullを返す。
◆Callableインターフェース
Runnableインターフェースのrun()は処理結果をスレッド開始元に戻すことがでません。
一方Callableインターフェースのcall()メソッドにタスクを実装して利用すると、処理結果をオブジェクトで返すことが可能になります。
様々なインターフェースが登場し混乱していましたが、まとめたらいくらか整理されました。
次の記事で非同期処理を記述するのに実際に今日まとめたクラスを使っていきます!
ここまで読んでくださりありがとうございました。