質問: synchronizedを使用方法で混乱しています。 javaを独学で勉強しております。synchronizedをインスタンスメソッドに使用したのですが、同期化できません。いくら考えてもわからなかったので、質問しました。ソースを記入します。 class test extends thread{ public void run(){ ss(); } public synchronized void ss(){ for(int x=1;x<=10;x++){ system.out.println(thread.currentthread().getname()); } } public static void main(string[] args){ test t1 =new test(); test t2 =new test(); test t3 =new test(); t1.start(); t2.start(); t3.start(); } } 実行すると、同期化されてなく、ランダムに表示されます。違うオブジェクトで参照しているから、ロックかけても意味がないのかなーとも思っていますが、 threadの拡張じゃなく、runnableの実装に書き換えると同期化されます。なぜでしょう?自分なりに精一杯考えましたがわかりません。分かる方、説明お願いできますでしょうか?
回答: no.3です。 そのrunnable継承版のソースコードだと、 たしかに同期化される...。 mxpxさんの書いた thread継承版のソースコードと runnable継承版のソースコードとでは、 「別物の」ソースコードになっているので、 この書き方のままでは両者を比較できない。 (※ソースコードの書き方の違いであって、 thread継承とrunnable継承の違いではない) /** *runnable継承版のmain() */ public static void main(string[] args){ test test = new test();//testのインスタンス作成(唯一) thread t1 = new thread(test);//第1スレッド作成 thread t2 = new thread(test);//第2スレッド作成 thread t3 = new thread(test);//第3スレッド作成 t1.start();//第1スレッド開始 t2.start();//第2スレッド開始 t3.start();//第3スレッド開始 /*この時点で、3つのスレッドが存在し、 そのいずれもが「唯一のtestインスタンスのrun()メソッド」 を定期的に呼び出すことになる (つまり3つのスレッドが競って1つのインスタンスのメソッドを呼び出す)。 いいかえると 「スレッド3つに、呼ばれるほう1つ」。 ってことで、その「呼ばれる」唯一のメソッドにsynchronized を付ければ当然、 そのメソッド呼び出しは同期化される。 */ } /** thread継承版のmain() */ public static void main(string[] args){ test t1 = new test();//第1testインスタンス(かつ第1スレッド)作成 test t2 = new test();//第2testインスタンス(かつ第2スレッド)作成 test t3 = new test();//第3testインスタンス(かつ第3スレッド)作成 t1.start();//第1スレッド開始 t2.start();//第2スレッド開始 t3.start();//第3スレッド開始 /*この時点で、3つのスレッドが存在し、 それぞれが「別々のtestインスタンスのrun()メソッド」 を定期的に呼び出すことになる (つまり3つのスレッドが競って1つのインスタンスの メソッドを呼び出すわけではない)。 いいかえると 「スレッド3つに、呼ばれるほうも3つ」。 呼ばれる側のメソッド1つに、 (いわば専属の)実行用スレッド1つが対応してる感じ。 よって同期も何もない。 */ }