Java SE 7徹底理解の2回目である今月は、並行処理のフレームワークについて紹介していきます。

 Javaは1.0がリリースされた当初から、スレッドを使用することができました。筆者もJava 1.0で簡単にスレッドが使えることに感動したことを覚えています。

 しかし、スレッドを安易に使ってしまうと、デッドロックやデータの破壊を引き起こしかねません。スレッドクラスは簡単に使えるものの、使いこなすには並列/並行処理についての適切な知識を必要としたのです。

 そこで、より簡単に並列/並行処理を使うためのフレームワークであるConcurrency UtilitiesがJ2SE 5.0で導入されました。

 Concurrency Utilitiesは非同期処理APIや、スレッドセーフで高性能な並行コレクション、ラッチやセマフォなどのロック機構、アトミック処理など並列/並行処理のためのさまざまな機能が含まれていました。

 Concurrency Utilitiesでは非同期処理にExecutorインタフェースを使用します。また、スレッドプールも提供されています。 このためThreadクラスを直接使う必要もなくなり、並列/並行処理を行なうためのハードルがかなり低くなったのです。

 しかし、その後ハードウェアのトレンドが大きく変わりました。J2SE 5.0がリリースされたのが2004年。当時はCPUのクロックの上昇が鈍くなり、その代わりにマルチコアのCPUが登場しはじめました。

 今では、家庭用のPCでも4コアは当たり前に使われていますし、サーバではより多くのコアを使用しています。

 このようにCPUのアーキテクチャが変化を遂げているのですから、ソフトウェアもそれに対応しなくてはいけません。つまり、複数のコアを遊ばせておかないようにする必要があります。

 そのためには、タスクをより細分化して、複数のコアにまんべんなく処理を行なわせなければいけません。

 ところがここで問題があります。

 Concurrency Utilitiesで導入されたExecutorインタフェースは細粒度のタスク処理には適していないのです。

 Executorインタフェースはある程度粒度の大きいタスクを想定して設計されています。このため、粒度が細かくなるとオーバヘッドが大きくなってしまい、パフォーマンスが落ちてしまいます。

 そこで、登場するのがJava SE 7で導入される予定のFork/Join Frameworkです。

 Concurrency UtilitiesはJCPのJSR 166において仕様策定が行なわれてきました。Fork/Join Frameworkは新たなJSRを起こすのではなく、JSR 166のアップデートとして仕様策定されています。両者を区別するために、Fork/Join FrameworkはJSR 166yと呼ばれます。

 JSR 166yはJSR 166と同様にDoug Lea氏が中心になって仕様策定が行なわれています。