1

プール、エグゼキューター、フューチャーのいくつかの実装をチェックしてしばらくの間SOを見回してきましたが、どれも私の目的に合わない...または少なくとも適切に実装できません。

クラスのライブラリがあり、すべて次のようになります。

class X implements Runnable {
   @Override 
   public void run() { 
    // do sth
   }
} 

それらを変更することはできません。

そして私のクラス:

class Controller {
   private int threadState;

   void threadStart() {
     // run a thread (made from any of the classes above)
     // and when it exits change the threadState value to V
   }
}

必要なのは、終了後に何らかのアクションを実行する threadStart() でスレッドを実行することだけですが、threadStart() 関数はすぐに渡されるはずです。

これをJavaまたは/およびGroovyで解決するための良いアイデアはありますか? ありがとう。

4

3 に答える 3

1

これを達成するための1つの可能な(しかしやや醜い)方法は、実行する前に、タスクを別の実行可能ファイルにラップすることです。ラッパーは、実際のタスクに委任し、完了したらコールバックメソッドを呼び出す責任があります。

void changeThreadState() {
    // This is your call back, in controller
}

void threadStart() {
    final X task = new X(); // task creation (variable has to be final)

    final Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            task.run();
            changeThreadState();
        }
    });

    t.start();
}

もちろん、例外処理やそのようなすべての優れた機能を追加します。

メソッドで直接スレッドを作成するのでthreadStartはなく、Executorまたは他の種類のスレッドプール構造を使用することもできることに注意してください。

于 2013-03-23T10:53:01.767 に答える
0

Groovyas演算子を使用して、オブジェクトにクロージャを強制することができRunnableます。また、列挙型は州にとってクールです:

class X implements Runnable {
    void run() {
        sleep 1000
        println "async task done"
    }
}

enum State { NOT_STARTED, DONE }

class Controller {
        State state = State.NOT_STARTED
        Thread t
        void threadStart() {
            t = Thread.start { new X().run(); changeState() } as Runnable
        }

        void changeState() { state = State.DONE }
}

controller = new Controller()
controller.threadStart()

assert controller.state == State.NOT_STARTED
controller.t.join()
assert controller.state == State.DONE
于 2013-03-23T11:49:17.943 に答える
0

runnable の開始クラスへの参照を追加し、run メソッドが終了したときに親クラスで changeState メソッドを呼び出すことができます。

于 2013-03-23T10:36:08.927 に答える