0

相互に依存する 3 つの (A、B、C) サービスを作成するタスクがあります。サービス A が起動するとサービス B が起動し、サービス B が起動するとサービス C が起動し、サービス C が停止するとサービス B が停止し、サービス B が停止するとサービス A が停止します。スレッドを開始し、ステータスオプションを使用して別のスレッドに切り替えることができました。私はJavaについてあまり知らないと言わざるを得ませんが、Javaを学び始めたばかりなので、これは初めてなので、助けや提案などは素晴らしいでしょう。

また、ほとんど同じクラスが 3 つあるので、これらの 3 つのクラスを 1 つに置き換える方法を教えてもらえますか? 何か方法はありますか?

これが私のコードです:

public class service_class {
    int status=1;
    public static void main(String[] args) {

        service_class service_class = new service_class();

        A1 a=new A1(service_class);
        B1 b=new B1(service_class);
        C1 c=new C1(service_class);

        a.start();
        b.start();
        c.start();

    }
}

class A1 extends Thread{
    service_class service_class;

    A1(service_class service_class){
        this.service_class = service_class;
    }


    @Override
    public void run() {

        try{
            synchronized (service_class) {
                 while(service_class.status!=1){
                        service_class.wait();
                    }

                    System.out.print("A started" + "\n");
                    service_class.status = 2;
                    service_class.notifyAll();

                    while(service_class.status!=7){
                        service_class.wait();
                    }
                    System.out.print("A stoped" + "\n");
                    service_class.status = 1;
                    service_class.notifyAll();
                }

        }catch (Exception e) {
            System.out.println("Exception 1 :"+e.getMessage());
        }

    }

}

class B1 extends Thread{

    service_class service_class;

    B1(service_class service_class){
        this.service_class = service_class;
    }

    @Override
    public void run() {

        try{
            synchronized (service_class) {

                    while(service_class.status!=2){
                        service_class.wait();
                    }

                    System.out.print("B started " + "\n");
                    service_class.status = 4;
                    service_class.notifyAll();

                    while(service_class.status!=6){
                        service_class.wait();
                    }
                    System.out.print("B stoped" + "\n");
                    service_class.status = 7;
                    service_class.notifyAll();
                }

        }catch (Exception e) {
            System.out.println("Exception 2 :"+e.getMessage());
        }

    }
}


class C1 extends Thread{

    service_class service_class;

    C1(service_class service_class){
        this.service_class = service_class;
    }

    @Override
    public void run() {

        try{
            synchronized (service_class) {
                 while(service_class.status!=4){
                        service_class.wait();
                    }
                    System.out.print("C started" + "\n");
                    service_class.status = 5;
                    service_class.notifyAll();

                    while(service_class.status!=5){
                        service_class.wait();
                    }
                    System.out.print("C stoped" + "\n");
                    service_class.status = 6;
                    service_class.notifyAll();
            }
        }catch (Exception e) {
            System.out.println("Exception 4 :"+e.getMessage());
        };

    }
}
4

3 に答える 3

3

ほぼ同じクラスが 3 つあるので、これらの 3 つのクラスを 1 つに置き換える方法を教えてもらえますか? 何か方法はありますか?

A3つのクラスの違いのように見え、次のBとおりCです。

  • 出力される名前文字列、および
  • それぞれがテストして設定する状態値。

したがって、これらをインスタンス変数に置き換えfinal、(統合された) クラス コンストラクターに渡される値で初期化します。


でも ...

延長Threadは一般的に悪い考えだと考えられています。まず、スレッド プーリングの使用が困難になります。より良いアプローチは、標準Threadクラスを使用し、Runnable構築時にインスタンスを渡すことです。実際、スレッド プールや Executor サービスなどを使用している場合は、自分でスレッドを作成して管理する必要さえありません。

待機/通知に関しては、より高いレベルの同期構造 ( などCountDownLatch) を使用する方が簡単です。

于 2013-03-21T12:45:11.473 に答える
1

CountDownLatchを使用する

ACountDownLatchは指定されたカウントで初期化されます。メソッドは、(他のスレッドによる) メソッドawaitの呼び出しによってカウントがゼロになるまでブロックcountDown()され、その後、待機中のすべてのスレッドが解放されます。私の提案は、次のようなスーパークラスを作成することです。

  • 初期カウントが 1 のラッチを提供します
  • そのクラスの別のインスタンス、またはCountDownLatch実行前に待機する を受け入れます
  • 開始時にラッチをデクリメントします
  • そのロジックをラップし、実際のコードが実装されるrun抽象メソッドを提供します。innerRun

    abstract class LatchedRunnable extends Runnable {
    
    private CountDownLatch latch=new CountDownLatch(1);
    private CountDownLatch wait;
    public Foo(LatchedRunnable waitFor) {
      this.wait=waitFor.latch;
    }
    public Foo(CountDownLatch waitFor) {
      this.wait=waitFor;
    }
    
    final run () {
     //wait for the other thread
     if (wait!=null) 
        try {wait.await();} 
        catch (InterruptedException e) {return;}
    
     //signal that we have started
     latch.countDown();
    
     //actually start
     innerRun();
    }
    
    protected abstract void innerRun(); //do stuff here
    }
    
    
    
    class Foo extends LatchedRunnable {
       Foo(LatchedRunnable waitFor) {super(waitFor);}
       protected void innerRun() {...}
    }
    
    class Bar extends LatchedRunnable { 
       Bar(LatchedRunnable waitFor) {super(waitFor);}
       protected void innerRun() {...}
    }
    
    Foo foo = new Foo(null);
    Bar bar = new Bar(foo);
    
于 2013-03-21T12:39:09.580 に答える