【Java】スレッドセーフとは?気になったので調べてみた。
どうもこんにちは。
突然ですが、皆さんは「スレッドセーフ」という言葉をご存知でしょうか? 私は思いましたよ、ええ。
「スレッドセーフってなんぞや!?」と。
そこで今回は、スレッドセーフについて調べてみました!
自分なりにまとめましたので、よければ参考にしてみてください。(※あくまでもJavaベースなのでご了承ください。)
スレッドセーフとは?
そもそもスレッドセーフとは何なのでしょう?気になったので、スレッドセーフについて調べてみました!
簡単に説明すると、「マルチスレッドでも大丈夫だよ」ということです。ちなみにマルチスレッドというのは、並行処理が発生するプログラムのことを意味します。
並行処理というのは読んで字のごとく「同時に処理を行う」という認識でいいかと。
スレッドセーフについてもう少し説明をすると、並行処理が発生するプログラムを使う環境で、複数のスレッドが同時に実行したり同じデータを扱っても壊れないよという意味です。
スレッドセーフな実装じゃないとどうなるの?
先ほどはスレッドセーフについて簡単に説明しました。しかし、スレッドセーフじゃなかったらどういう事象が起こるのでしょうか?
これまた簡単に例を挙げますと、複数人が使うことを前提としているアプリケーションでスレッドセーフを考慮しておかないと「Aさんしか見られない情報なのに、意図せずBさんがAさんの情報を見ることができちゃう」という末恐ろしい状況になりかねないのです。。
どうやったらスレッドセーフにできるのか
上の事象が起こると相当困りますよね。どう責任取ってくれるんじゃあ!!とユーザーが乗り込んできてもおかしくありません。
そうならないために、どうやったらスレッドセーフな実装にできるのかというと…
- クラス変数、インスタンス変数は使わずにローカル変数を使う
- staticに使用し変更のない定数はローカル変数以外でも問題ない
上記のことを考慮しながら実装をするといいでしょう。
何故、クラス変数・インスタンス変数を使用してはいけないのか。その理由として、「クラス変数・インスタンス変数」はヒープエリアに格納されます。
ヒープエリアというのは、主にインスタンスを管理するメモリ領域です。
クラス変数・インスタンス変数はこのメモリ領域に保持され、複数のスレッドから参照することができちゃいます。
ここで先ほどの事象を例に出すと、【複数の人が使用する共有データでそれぞれが処理を実行することにより、ヒープエリアに格納され保持されたデータを他の人へ意図せず渡してしまう】という訳ですね。
それでは逆に、何故ローカル変数を使うとスレッドセーフな実装になるのか。その理由としては、 ローカル変数はJavaのスタックエリアに格納されるから。
というのも、スタックエリアというのはプログラムの実行を制御するための領域です。
スタックエリアは、スレッド毎に異なるメモリ領域に保持されるため一つのスレッドからしか参照されず、書き換えられたりする恐れがありません。
ちなみに、スタックエリアで処理されると上から順に実行され、実行済みの処理はどんどん破棄されていく仕組みです。
このスタックエリアちゃんは真面目な子なので、一つずつ処理をして処理済みのものはぽいっと捨てちゃう訳です。
なので、並行処理をしてもそれぞれの異なるメモリ領域に保持されているため壊れませんし、他の人から参照されたり書き換えられたりする心配もないって事ですね!
注意点
基本的には上記のことを意識して実装すれば良いのですが、Javaプログラムではクラス変数・インスタンス変数を使用しなくても意図せずJSPで使用してしまう事がありますので注意しましょう。
まとめ
いかがでしたか? 今回はスレッドセーフについて調べていきました!
私自身、スレッドセーフについて全く無知だったのでこれからはきちんと意識しながら開発に取り組んでいきたいなと感じました。
いやぁ、無知って怖いですね…。
それでは、今回はこの辺で。
また次回お会いしましょう!