• ベストアンサー

synchronizedが解りません。

synchronized( a ) { a.add(); } ブロック文で aオブジェクトをロックしてるはずなんですが 結果を見ると出来てないようです なぜうまくいかないんでしょうか? 教えてください。 class Test extends Thread { feet a = new feet(); public static void main( String args[] ){ for( int i = 0; i < 3; i++ ){ Test b = new Test(); b.start(); } } public void run() { synchronized( a ) { a.add(); } } } class feet{ int n, m; void add(){ n++; System.out.println( n + " " + m ); try { Thread.sleep( 1000 ); }catch( InterruptedException err ){ } m++; System.out.println( n + " " + m ); } }

  • Java
  • 回答数2
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
  • auty
  • ベストアンサー率58% (284/486)
回答No.1

異なるオブジェクトb1,b2,b3のインスタンスメソッドadd()を実行しているので、 実行されるメソッドadd()は、全て異なるのではないでしょうか。

startover
質問者

お礼

回答ありがとうございます! なるほど! 異なるインスタンスメソッドですか! 教えて頂きありがとうございます。

その他の回答 (1)

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.2

ふつうは、次のように、同期化が必要なオブジェクト側でsynchronizedを使い、自分の資源を防備します。(全角スペースを半角スペースに変えてからコンパイルしてください。) --------------------------------------- class ThreadTest extends Thread {  static Feet a = new Feet(); //ただ一つのFeetオブジェクト  public static void main( String args[] ){   for (int i = 0; i < 3; i++){    ThreadTest b = new ThreadTest();    b.start();   }  }  public void run() {   a.add();  } } class Feet{  int n, m;  synchronized void add(){   n++;   System.out.println    (Thread.currentThread().getName() + ": " + n + " " + m);   try {    Thread.sleep(1000);   }   catch( InterruptedException err ){    err.printStackTrace();   }   m++;   System.out.println    (Thread.currentThread().getName() + ": " + n + " " + m);  } } -------------------------------

startover
質問者

お礼

回答ありがとうございます staticを使うんですね! コードで教えて頂きどうもです。

関連するQ&A

  • synchronized を施しているのに・・・

    java初心者です。宜しくお願い致します。 あるスレッドがsynchronizedのメソッドを実行すると、そのメソッドの仕事は連続したひとかたまりの処理として実行される、と習いました。 なるほど、と思ったのですが、 自分で次のようなコードを書いてみると、そのようになりません。 ならない時もある、と言ったほうが正確でしょう。 具体的には、 0 1 別の処理 2 や、 0 別の処理 1 2 となったりします。 ご面倒でしょうが、コードを書きますので、解析して解りやすく教えて頂けると嬉しく思います。 class MyRunnable10 implements Runnable{ public synchronized void run(){ for(int i=0 ; i<3 ; i++){ System.out.print(i + " "); } } } class MyRunnable20 implements Runnable{ public void run(){ System.out.print("別な処理"); } } public class Exec2 { public static void main(String[] args) { Runnable m = new MyRunnable10(); Runnable m2 = new MyRunnable20(); Thread t1 = new Thread(m,"A"); Thread t2 = new Thread(m2); t1.start(); t2.start(); } }

    • ベストアンサー
    • Java
  • synchronizedによる同期化について

    Javaで開発しています。 synchronizedで同期化したく、サンプルを作ってみたのですが上手く同期化が出来ていないようなので質問しました。 以下プログラム public class Synch{ public static void main(String[] args){ final Something obj = new Something(); new Thread(){ public void run(){ synchronized(this){ try{ obj.write(); } catch(Exception e){ }notify();} } }.start(); new Thread(){ public void run(){ try{ obj.read(); } catch(Exception e){ } } }.start(); } } class Something{ private int x = 10; private int y = 100; public synchronized void write(){ if(x < y){ System.out.println("write:x < y"); } else if(x > y){ System.out.println("write:x > y"); } for(int n = 0;n < 100;n++){ x++; y++; } for(int m = 0;m < 150;m++){ y--; } if(x < y){ System.out.println("write:x < y"); } else if(x > y){ System.out.println("write:x > y"); } } public synchronized void read(){ if(x < y){ System.out.println("read:x < y"); } else if(x > y){ System.out.println("read:x > y"); } } } このプログラムを実行すると、時々readのほうが先に表示されてしまいます。 実行環境はEclipse2.1.3です。 readが先に表示されるのは仕方のないことなのでしょうか? それともプログラムがいけないのでしょうか? ご存知の方いらっしゃいましたら教えて頂けないでしょうか。 不足がありましたら仰ってください。

    • ベストアンサー
    • Java
  • 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の実装に書き換えると同期化されます。なぜでしょう?自分なりに精一杯考えましたがわかりません。分かる方、説明お願いできますでしょうか?

    • ベストアンサー
    • Java
  • スレッド間の送受信のコードについて

    下記のコードは、(以前お教え頂きました)『synchronized』を使用した、スレッド間の 送受信のコードですが、その代わりに、Interruptとか、Thread.sleep()を使用した、 コードに変更してみたいと思います。 Q1)そのコードをお教え頂けないでしょうか? class T_thread { public static void main(String args[]) { new rcvInterrupt().start(); } } class genInterrupt extends Thread { private rcvInterrupt target; genInterrupt(rcvInterrupt targetx) { this.target = targetx; } public void run() { System.out.println("genInterupt start"); for (int i = 0; i < 10; i++) { while (!target.isWaited) { // rcvInterruptがsynchronizedブロックに入るまで待ち合わせ // これがないと連続してsynchronizedしてしまう可能性がある } synchronized (target) { target.notifyAll(); target.isWaited = false; System.out.println("notify"); } } } } class rcvInterrupt extends Thread { volatile boolean isWaited; public synchronized void run() { new genInterrupt(this).start(); for (int i = 0; i < 10; i++) { try { isWaited = true; wait(); System.out.println("get interrupt cnt=" + i); } catch (InterruptedException e1) { } } } } 以上

    • ベストアンサー
    • Java
  • java iを1づつ増やすプログラムと2づつ増やすプログラム

    次のようにすればiを1づつ増やして表示されます。 class Calc{   int i=1;   int add(){     return i++;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 1 i = 2 i = 3 しかし次のように2づつ増やそうとすると、 class Calc{   int i=1;   int add(){     return i+2;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 3 i = 3 i = 3 このようになってしまいます。どこがおかしいのでしょうか?

    • ベストアンサー
    • Java
  • Threadに関するの質問

    このプログラムに synchronized , wait(), notify()を加えることで、 stackBody[]配列をオーバーやアンダーフローしないようにできるのでしょうか。お助け下さい! public class test { public static void main(String args[]) { Stack stack = new Stack(5); Pusher pusher = new Pusher(stack); Popper popper = new Popper(stack); pusher.start(); popper.start(); } } class Stack { private int stackSize; private int stackPointer; private int stackBody[]; public Stack(){ this(10); } public Stack(int size){ stackSize = size; stackBody = new int[size]; stackPointer = 0; } public void push(int value){ if(stackSize == stackPointer){ // } stackBody[stackPointer++] = value; } public int pop(){ if(stackPointer == 0){ // } return stackBody[--stackPointer]; } } class Pusher extends Thread { Stack s; public Pusher(Stack s) { this.s = s; } public void run() { int n, interval; for(int i = 0; i < 10; i ++) { n = (int)(100.0 * Math.random()); interval = (int)(100.0 * Math.random()); s.push(n); System.out.println("Pusher:" + n); try{ Thread.sleep(interval); }catch(InterruptedException e) {} } System.out.println("Push 終了"); } } class Popper extends Thread { Stack s; public Popper(Stack s) { this.s = s; } public void run(){ int n, interval; for(int i = 0; i < 10; i++){ interval = (int)(100.0 * Math.random()); n = s.pop(); System.out.println("Popper:" + n); try{ Thread.sleep(interval); }catch(InterruptedException e) {} } System.out.println("Popper 終了"); } }

    • ベストアンサー
    • Java
  • [javaプログラムについて] うまく動きません。

    import java.*; class Test { void main() { Th th1 = new Th("01スレッド"); Th th2 = new Th("02スレッド"); th1.start(); th2.start(); } } class Th extends Thread { void run(String pri) { for (int i=0;i<5;i++) { System.out.println(pri + " : " + i); } } } スレッドの使い方がいまいちよく分かりません。 どこが間違っているのか教えてください。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • NoSuchMethodErrorが解決できません。

    実行時エラーNoSuchMethodErrorが出て困っています。 どこを修正すればいいのでしょうか? class A implements Runnable{ int x; int y; public void run(){ for(int i = 0;i < 100;i++){ x++; y++; System.out.println("x="+x+"y="+y); } } } class B{ public static void main(String args[]){ new Thread(new A()).start(); new Thread(new A()).start(); } }

    • ベストアンサー
    • Java
  • デッドロックに関して1

    下記のサンプルソースは、デッドロックを起こすソース なのですが、 public class Deadlock extends Thread { public static Object l1 = new Object(); public static Object l2 = new Object(); private int index; public static void main(String[] a) { Thread t1 = new ThreadA(); Thread t2 = new ThreadB(); t1.start(); t2.start(); } private static class ThreadA extends Thread { public void run() { synchronized (l1) { System.out.println("スレッド1: l1に対するロックを取得"); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("スレッド1: l2のロックの開放待ち"); synchronized (l2) { System.out.println("スレッド1: l1、l2に対するロックを取得"); } } } } private static class ThreadB extends Thread { 文字数オーばーのため削除 } これを参考に、Junitでデッドロックを起こすサンプルを作りたいです。 MultithreadedTestCaseと ControllableTestThreadを使い サンプルを作りたいのですが、 英語が良くわからず苦戦しております。 なにか、よいアドバイスをいただけませんでしょうか? よろしくお願いします

    • ベストアンサー
    • Java
  • 静止的フィールドについて教えてください

    教えてください。以下のプログラムだとして、 class Box { static int a = 0 ; int b = 0 ; int c = a+4; } class sample { public static void main(String[] args) { Box n = new Box() ; n.a-- ; n.b-- ; n.c[1]-- ; System.out.println("n.a= "+n.a);//-1 System.out.println("n.b ="+n.b);//-1 System.out.println("n.c[2]="+n.c[2]);//4 Box m = new Box() ; m.a++ ; m.b++ ; m.c[2]++ ; System.out.println("n.a ="+n.a);//0 System.out.println("n.b ="+n.b);//-1 System.out.println("n.c[2] ="+n.c[2]);//4 System.out.println("m.a ="+m.a);//0 System.out.println("m.b ="+m.b);//1 System.out.println("m.c[2] ="+m.c[2]);//4 } } Box nの中のn.aの値はわかります。 ですが、Box mの中のn.aは、a がstaticフィールド(?)なので元の0に戻りますが、m.aがなぜ0なのかわかりません。 そもそもstatic int = ●; のときは、静止的intと教わったのですが、どういう現象が起こるのかいまいちです。 よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう