javaでのスレッド制御(joinとsynchronized)

javaでは、スレッドを立てて処理を並列に行うことができます。
しかし、並列に処理を行う際、処理順を制御しなければならないことがあります。

処理順の制御方法として基本的な方法として、joinを使う方法とsynchronizedを使う方法があります。
joinを使うことで、スレッドが終わるのを待つことができます。
また、synchronizedを使うことで、複数のスレッドが同じ処理を同時に行わないように制御することができます。

以下は、joinやsynchronizedを使って制御を行うサンプルコードです。
1つのスレッドで5回の処理を行うサンプルであり、そのスレッドを2つ立てます。
また、スレッド間で同一のオブジェクト(staticなオブジェクト)を共有しており、そのオブジェクトでは合計何回処理が行われたのかをカウントしています。

制御を行わない場合は、どちらのスレッドが先に処理するのかが定まりません。また、共有オブジェクトでのカウントを2つのスレッドで同時に行うためにカウントも上手く行きません。
joinによる制御を行う場合は、スレッド1の5回の処理が終わってからスレッド2の処理に移る、という制御が可能になります。
synchronizedによる制御を行う場合は、スレッド1とスレッド2が同時に動いても、共有オブジェクトでのカウントは同時には行われず、上手くカウントすることができます。

【サンプルコード】

・ThreadMain.java

・ThreadBody.java

・ThreadCounter.java

【実行結果】

・そのまま実行した場合

・①のコメントアウトを外した場合(join)

・②のコメントアウトを外した場合(synchronized)


いかがでしたでしょうか。

性能要件を満たすためにスレッドが必要になることがあるのですが、その際にスレッド制御の方法を知らないと処理の同期が取れずに障害になってしまうことが多いです。
今スレッドを使っていなかったとしても、いつ使うようになるかわかりませんので、こういったスレッド制御の方法を知っておいて損はありません。

では、また次回!

単なるstaticとsingletoneパターンの違い

オブジェクト指向プログラミングのプログラミング手法で、「singleton(シングルトン)」と呼ばれる手法があります。
この手法は、プロジェクト内で共通的に使われるインスタンスを1つだけ予め作成し、外部のクラスにはそのインスタンスを使用させる、という手法です。

この手法を学んだ時に「インスタンスを1つにすれば良いなら、クラス変数やメソッドをstaticにするだけで良いのでは?」と思ったので、試しにテストコードを書いてみました。
単純なstaticでは使用者側で好きにインスタンスを作成できる(実態としては1つ)のですが、singletonとしてインスタンスを作成すれば使用者側でのインスタンス作成を防ぎ、明示的にインスタンスを1つにできることを確認しました。

【テストコード】

・StaticMemory.java

・SingletoneMemory.java

・MemoryTestMain.java

【実行結果】


いかがでしたでしょうか。

「singleton」は、GoFの23個のデザインパターンの内の1つに数えられる手法です。
デザインパターンはオブジェクト指向プログラミングのプログラミング手法をまとめたものであり、効率的なプログラミングを行う上で有効ですので、これからも紹介していくと思います。

では、また次回!