2012年04月04日

java.util.concurrent 〜Executor その1〜


今日からはExecutorインターフェイス関連をやっていきます。Executorは非同期処理を実行するためのインターフェイスです。java.util.concurrentで一番重要そうなインターフェイスですね。まずは超簡単なサンプルから見ていきます。

ExecutorとRunnable
最初はExecutorとRunnableを用いた単純なサンプルから。
public static void main(String[] args) {

	//実行させるタスクをRunnableで作成
	Runnable task = new Runnable(){

		@Override
		public void run() {
			//三秒待つ(java.util.concurrent.TimeUnitを使用)
			try {
				TimeUnit.MILLISECONDS.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Hello java.util.concurrent World");
		}

	};

	//シングルスレッドを生成するためのExcutorを作成する
	Executor executor = Executors.newSingleThreadExecutor();

	//タスクを実行
	executor.execute(task);

	//※注意
	//Executorインターフェースはタスク終了後もスレッドを上げ続けるので、このままだと
	//Mainスレッドは終わりません。

}

・非同期処理の作成
まずはRunnableを匿名クラスで生成して、非同期のタスクを作っています。内容は3秒待ってから「Hello java.util.concurrent World」と出力するだけです。

・Executorを作成
続いて主役であるExecutorを作成します。といっても、Executorはインターフェイスなので、Executorsというクラスに作成してもらいます。このExecutorsは後述するExecutorService、ScheduledExecutorService、ThreadFactory、および Callableを作成するためのファクトリです。ちなみにExecutorはExecutorServiceやScheduledExecutorServiceのスーパーインターフェイスです。Executorsは用途によって様々なメソッドが用意されていますが、今回は単純に「1つのスレッドを実行するExcutorService」を作成するExecutors.newSingleThreadExecutor()を使用します。

・タスクを実行
Executor.execute()を呼び出し、引数にRunnableを渡してやります。ここで気をつけて欲しいのはこのままだとmainスレッドは終了しないということです。コメントにも記しましたがExecutorインターフェースはタスク終了後もスレッドを上げ続けるからです。じゃあどうするか?というと、Executorではどうすることもできません。実はExecutorはexecuteというメソッドしか持っていないからです。この問題に対処するにはExecutorServiceが必要になってきます。

ExecutorServiceとRunnable
次はExecutorServiceを試してみます。ExecutorServiceはExecutorの拡張インターフェイスです。
public static void main(String[] args) {

	//実行させるタスクをRunnableで作成
	Runnable task = new Runnable(){

		@Override
		public void run() {
			//三秒待つ(java.util.concurrent.TimeUnitを使用)
			try {
				TimeUnit.MILLISECONDS.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Hello java.util.concurrent World");
		}

	};

	//シングルスレッドを生成するためのExecutorServiceを作成する
	ExecutorService executor = Executors.newSingleThreadExecutor();

	//タスクを実行
	executor.execute(task);

	System.out.println(executor.isShutdown());

	//Excutorの処理が終了したらスレッドを終了させる命令
	executor.shutdown();

	//仮にこの時点でスレッドが終了していなくてもshutdownが呼ばれていればisShutdownの結果はtrue
	//「起動したスレッドが終了しているか」はisTerminated()で検査できる
	System.out.println(executor.isShutdown());
}

Executors.newSingleThreadExecutor()を呼び出し、execute()で実行するまでは全く前回と同じです。ただし受け取りがExecutorServiceなっていることに注意。
・非同期処理スレッドの終了
executor.shutdown()で非同期処理が終了したらスレッドをシャットダウンさせることができます。非同期処理がいつ終わるか判らないことを考えると「シャットダウン予約」のようなニュアンスでしょうか。コメントにあるとおり、「非同期処理が終了し、スレッドがシャットダウンされたかどうか」を調べるにはExecutorService.isTerminated()を使用します。

次回は非同期処理からの戻り値の取得についてです。
posted by sandman at 22:12| Comment(0) | Java | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。