0

セマフォのような共有変数のケースを実装しようとしています。その中で、順番に実行する必要がある3つのスレッドがあります。以下は私のプログラムです。どこが間違っているか教えていただけますか?

class Test2{    
    private volatile static int sharedvarNEXT = 1;
    public synchronized static int getSharedvarNEXT(){
        return sharedvarNEXT;   
    }
    public synchronized static void setSharedvarNEXT(int val){
        sharedvarNEXT = val;    
    }
    public static void main(String[] s){
        new classACaps().start();
        new classAsmall().start();
        new class1().start();
    }
}

class classACaps extends Thread{
    public void run(){
        try{
            for(char c='A';c<='Z';c++){
                if(Test2.getSharedvarNEXT() == 1){
                    System.out.println(c);
                    Test2.setSharedvarNEXT(2);
                    notify();
                } else {
                    wait();
                }
            }
        } catch(Exception e){
            System.out.println("caught in A");      
        }
    }
}

class classAsmall extends Thread{  
    public void run(){
        try{
            for(char c='a';c<='z';c++){
                if(Test2.getSharedvarNEXT() == 2){
                    System.out.println(c);      
                    Test2.setSharedvarNEXT(3);
                    notify();
                } else {
                    wait();
                }
            }
        } catch(Exception e){
            System.out.println("caught in a");      
        }
    }
}

class class1 extends Thread{
    public void run(){
        try{
            for(int c=1;c<=26;c++){
                if(Test2.getSharedvarNEXT() == 3){
                    System.out.println(c);
                    Test2.setSharedvarNEXT(1);
                    notify();
                }else {
                    wait();
                }
            }
        } catch(Exception e){
            System.out.println("caught in 1");      
        }
    }
}

期待される結果は次のようになります: A、a、1、B、b、2......

4

2 に答える 2

3

その中で、順番に実行する必要がある3つのスレッドがあります。

シーケンシャルに実行しているわけではありません。3 つのスレッドを同時に実行しています。これは、3 つの個別のスレッドを開始したときに起こることの性質です。

これらのスレッドは、互いにまったく同期していませ。要件を考えると、まったく 3 つのスレッドが必要なようには思えません。

さらに:

  • synchronizedブロックはありません。両方ともwait()、呼び出されたモニターを所有するスレッドによってのみnotify()呼び出すことができます
  • のインスタンスでwait()andを使用することは、 の内部で使用されるため、強くお勧めしません。同期/待機/通知のためだけに別のオブジェクトを作成することをお勧めします。notify()ThreadThread
  • あなたの例外処理は、最初の問題を隠してきた例外を完全に無視します。例外を決して無視しないでください - そして、一般に、裸のキャッチExceptionをまったく避けるようにしてください。
于 2013-10-02T19:46:24.647 に答える
1

呼び出しnotify()とメソッドwait()内でのrun()呼び出しは基本的に

this.notify();

あなたThreadの はsynchronizedthis Threadインスタンスにありません。

notify()モニターを所有していない場合はできません。synchronizedその上で。取得したすべての例外を飲み込んでいます。

于 2013-10-02T19:46:10.260 に答える