synchronizedはどんな時に使うの?ということで、
これまで仕事ではなかなか登場させる機会がありませんでしたので、
いまさらではありますが、今回はjavaのsychronizedを触れてみようと思いました。
synchronizedって?
マルチスレッド処理における排他が必要な処理にて使用します。
synchronizedをつけることによって、あるスレッドがメソッド(またはブロック)を
処理している間、他のスレッドは処理が終わるまで待機することになります。
実際にやってみよう
まず、スレッドにて処理される以下ようなクラスを作成します。
public class ThreadExecutor { private int total = 0; synchronized public void add(int num) { int addResult = total + num; // sleepしているのはこれがないと高速で処理が終わってしまうので、 // thread処理されていることが目に見えて判断しにくいためです。 try { Thread.sleep(1000L); } catch (Exception e) { e.printStackTrace(); } total = addResult; } public void print() { System.out.println("total is " + total); } }
やっていることは単純です。
クラス変数として合計値のフィールドをもっており、
addメソッドに渡された引数を足しこんでいくというものです。
次に以下のように実際にスレッドを生成してThreadExecutorクラスを実行する
クラスを作成します。
public class ThreadSample implements Runnable { ThreadExecutor executor; public ThreadSample(ThreadExecutor executor) { this.executor = executor; } public static void main(String[] args) { // 同一のThreadExecutorクラスを別々のスレッドから使用する ThreadExecutor executor = new ThreadExecutor(); ThreadSample threadSample = new ThreadSample(executor); Thread thread1 = new Thread(threadSample); Thread thread2 = new Thread(threadSample); thread1.start(); thread2.start(); } @Override public void run() { for (int i = 0; i < 10; i++) { executor.add(1000); executor.show(); } } }
まずはsyncrhonizedをつけないとどうなるのか?
ThreadExecutorクラスのaddメソッドに上記サンプルではsynchronizedがついてますね。
まずはこれをつけないとどうなるのか?
結果はこうなります。
total is 1000 total is 1000 total is 2000 total is 2000 total is 3000 total is 3000 total is 4000 total is 4000 total is 5000 total is 5000 total is 6000 total is 6000 total is 7000 total is 7000 total is 8000 total is 8000 total is 9000 total is 9000 total is 10000 total is 10000
これはまずいですね。
例えばtotalの変数値が自分の銀行口座だとして考えてみましょう。
2箇所のATMから同時にこの口座に1000円ずつ10回お金を振り込んだ
というようなイメージだとわかりやすいかと思います。
本来であれば、20000にならないとおかしいですが、
排他をかけず2つのスレッドがほぼ同時に処理してしまっているので、
合計値の更新がうまくできていないですね。
それではsyncrhonizedをつけてみましょう。
結果はこうなります。
total is 1000 total is 2000 total is 3000 total is 4000 total is 5000 total is 6000 total is 7000 total is 8000 total is 9000 total is 10000 total is 11000 total is 12000 total is 13000 total is 14000 total is 15000 total is 16000 total is 17000 total is 18000 total is 19000 total is 20000
しっかり排他がかかっていて、正しく更新されていますね。
まとめ
このようにsynchronizedをメソッドに付与してあげることで、
処理に排他がかかるということがわかりました。
20代前半までは東京で音楽をやりながら両手の指以上の業種でアルバイト生活をしていましたが、某大手プロバイダのテレアポのバイトでPCの知識の無さに愕然とし、コンピュータをもっと知りたい!と思ったことをきっかけに25歳の時にITの世界に未経験で飛び込みました。
紆余曲折を経て、現在は個人事業主としてお仕事させていただいており、10年ほどになります。
web制作から企業システム構築、ツール開発など、フロントエンドもバックエンドもサーバーもDBAも依頼があれば何でもやってきた雑食系エンジニアです。
今風にいうとフルスタックエンジニアということになるのでしょうか??
→ 詳細プロフィールというか、生い立ちはこちら
→スキルシートをご覧になる場合はこちら
→お仕事のご依頼やお見積りなどお問い合わせはこちらから!