0

変更する元のプログラム コード:

/このメソッドは定期的に呼び出され、db からデータを取得し、それにいくつかの操作を実行し、結果をファイルに格納します。このファイルは、すべての処理の最後に ftp 経由で送信されます/

void pullData(){
    while(!stopped){
        rows= getRowsFromDb();

        for (row: rows){
            newRow= process(row);
            rowsContainer.add(newRow)
        }

        writeToFile(rowsContainer);
        sendFileSomewhere();
    }
}

次に、このコードを変更して、次のコマンドを発行できるようにする必要があります。1 行のみを処理します。1 行スキップします (コマンドは後で追加します)。これを行うために、アプリケーションは一時停止モードになり、上記で概説した 2 つのコマンドのいずれかを取得するまで行を処理しません。また、一時停止モードから再開して、通常の処理に戻すこともできます。

問題はこれをどのように行うかではなく、それを行う正しい方法です。

(1) 誰かが各操作のブール値フラグを提案しました。これはかなり悪い考えです。多くの理由でフラグを避けることをお勧めします (スタック オーバーフローについても議論されているものもあります)。

(2) もう 1 つのアイデアは、isSuspended に bool フラグを使用し、コマンドに enum を使用することでした。これは (1) よりも優れていますが、アプリは最後のコマンドがどれであるか、およびそれが中断モードにあるかどうかを確認し、それに応じて動作する必要があるため、多くはありません。

(3) アプリケーションを分割して Strategy パターンを使用することを考えていました。各コマンドは、アプリケーションで独自のメソッドを取得します。これはもう少し複雑ですが、私にはずっときれいに見えます。

何を提案しますか (私がリストしたオプションから選択する必要はありません。同様の状況をどのように処理したかを聞きたいです)?

4

3 に答える 3

2

次のようなタスクでExecutorServiceを使用します

private Future lastTask = null;

// only run one task at a time.
if (lastTask != null) lastTask.cancel(true);

lastTask = executorService.submit(new ProcessOnRowRunnable());
// or
lastTask = executorService.submit(new ProcessPendingRowsAndStopRunnable());
// or
lastTask = executorService.submit(new ProcessAllRowsUntilCancelledRunnable())

// later
future.cancel(true);

注:ループは割り込みを受け入れる必要があります。そうしないと、スレッドが中断されたからといってループが停止することはありません。使用できます

while(conditions && !Thread.curentThread().isInterrupted()) {
     // do work
}
于 2012-12-12T16:30:42.653 に答える
1

有限ステート マシン (または列挙型に基づいて単純に状態駆動されるサブセット) を使用する前に、これを何度も行ってきました。大きな利点は、FSM を検証し、大量の影響を受けない管理可能なものを維持できることです。フラグの問題

図 3. 簡単な状態図: (ここから)

図 3. 簡単な状態図

私は個人的に FSM を使用して、オブジェクト (この場合は注文) に適用できるアクションを管理し、RFC-822 電子メール メッセージの解析を管理し、ハードウェアを制御しました。

状態駆動型ループの非常に単純ですが機能的な例:

state = S_Starting;
while(state != S_Finished){

    switch (state){
        case S_Starting:
             // do something 
             state = S_Running;
             break;

        case S_Running
             rows= getRowsFromDb();

             for (row: rows){
                  newRow= process(row);
                  rowsContainer.add(newRow)
             }
             state = S_HandleReceipt;

             break;

         case S_HandleReceipt:
             writeToFile(rowsContainer);
             sendFileSomewhere();

         case S_Paused:
             if (some_other_test){
                 state = S_Running;
             }
             break;
    }
    if (some_test_for_finished) {
        state = S_Finished;
    } else if (some_test_for_pause) {
                  state = S_Paused;
    }
}

参照:

C# の階層ステート マシンStatelessは、残念ながらまだ Java に移植されていませんが、優れたツールです。

于 2012-12-12T17:19:32.727 に答える
1

メッセージを渡す ITC が必要だと思います。

while true
  msg = getMsgFromQueue
  case msg 
    skipARow: skip();
    processARow: process();
    doSomethingElse: 
于 2012-12-12T16:52:56.573 に答える