1

この問題の原因を突き止めることができません。

問題 :

1) アプリケーションのタイマーを設定するために Thread.Sleep 関数を使用しています。

2) ユーザーが webPage に入るとすぐにタイマーが開始されます。ユーザーがリンクをクリックすると、タイマー (スレッド) が停止し、新しいタイマーが開始します。

3) たとえば 3 秒間アクティビティがない場合、タイマーが終了し、Web ページに関連付けられているワークフローも終了します。

コード :

DownloadSummariesPage.java

public DownloadSummariesPage(){

 abc = new SimpleThread(this);

Link<Void> link = new Link<Void>("downloadSummaryLink") {

public void onClick() {

                    boolean threadStatus = abc.checkStatus();

                    if (threadStatus) {
                        abc.interrupt();
                        abc.stop();
                        abc = new SimpleThread(DownloadSummariesPage.this);
                        abc.start();
                        } 
                    else 
                        {
                        LOG.debug("thread is dead now");
                        endWorkflow();
                        LOG.debug("ending the workflow");
                        setResponsePage(MenuPage.class);                        
                        }
                     }

};
abc.start();
}


public void endWorkflow() {
    abc.interrupt();
    abc.stop();
    boolean downloadReport = false;
    LOG.debug("before action 201 inside endworkflow");
    Map<String, Serializable> inputs = new HashMap<String, Serializable>();
    inputs.put("downloadReport", downloadReport);
    try {
        wf.doAction(id, 201, inputs);//do not worry about this its for workflow
        String empty = "";
        populateDownloadReportDatabase(empty);

        setResponsePage(MenuPage.class);
    } catch (Exception e) {
        LOG.debug("Exception while performing 201 workflow, getControlCancel "
                + e);
    }
}
}

スレッドを作成する次のクラスは SimpleThread.java です

class SimpleThread extends Thread {
private static final Logger LOG = Logger.getLogger(SimpleThread.class);

boolean stillActive = true;
DownloadSummariesPage dsp;

SimpleThread(DownloadSummariesPage dp) {
    this.dsp = dp;
}

public void run() {
    // 5sec timer
    LOG.debug("inside run method");
    try {
        Thread.sleep(3000);
        stillActive = false;
    } catch (InterruptedException e) {
        LOG.debug("Exception in thread " + e);
        e.printStackTrace();
    }
    LOG.debug("before endworkflow");
    dsp.endWorkflow();//so this is what i actually want to do...
    LOG.debug("at the end of simplethread");

}

public boolean checkStatus() {
    return stillActive;
}
}

ケース :

1) Whats Happening : ユーザーがスレッドにログインし、ユーザーがリンクをクリックするとスレッドが停止し、ユーザーが再度クリックすると新しいスレッドが作成され、ユーザーが 3 秒間何もしないと、SimpleThread クラスの stillAlive 変数が false に設定されます。そして今、ユーザーがその終了をクリックすると、ワークフローは完全に終了します...

2)私が望むもの: ユーザーがログインしてスレッドが開始され、ユーザーによるアクティビティがない場合は、変数 stillAlive が false に設定され、dsp.endWorkflow(); ステートメントがワークフローを終了する必要があります。右 ?しかし、関数内に到達した後に停止するだけで、endWorkflow()実際にはワークフローを終了しません...

これを理解していただければ幸いです。理解しやすいように最善を尽くしました。御時間ありがとうございます..

助けていただければ幸いです..

4

1 に答える 1

1

ですから、ここにはいくつかの奇妙なことがあります。
最初に、スレッドが 3 秒間中断することなくスリープすると仮定すると、メソッドdsp.endWorkflow()から再度呼び出す場所が呼び出されます。 第二に、フラグはonClick

stillAlivevolatile

boolean volatile stillActive = true;

考えられるエラー/バグは、このセクションで発生します。

if (threadStatus) {
abc.interrupt();
abc.stop();// you cannot get to this like just after interrupt, maybe thread abc goes first
abc = new SimpleThread(DownloadSummariesPage.this);
abc.start();
} 

スレッドがスリープしているときに中断してから停止すると仮定しますが、中断した直後(停止する前)にスレッドが作業を終了する可能性があります。したがって、これは停止するかreturn、スレッドがキャッチに達したときに停止することをお勧めします。

    try {
        Thread.sleep(3000);
        stillActive = false;
    } catch (InterruptedException e) {
        LOG.debug("Exception in thread " + e);
        e.printStackTrace();
        return;//////give up the rest work. so you don't need to call the stop too.
    }

エラーは、ユーザーがキャンセルまたは新しいダウンロードをクリックせず、スレッドがスリープ状態を終了して を呼び出すと仮定すると、dsp.endWorkflow()このメソッドで何が起こっているのでしょうか?

public void endWorkflow() {
    abc.interrupt();
    abc.stop();//error here!
    boolean downloadReport = false;//this is unreachable
}

見てください、あなたはこのメソッドをスレッドごとに呼び出してabcいます。エラーは、 を に設定する前に、メソッドのすぐ内側でスレッドを強制終了していることdownloadReportですfalse。だからこうなるのかもしれません。

public void endWorkflow() {
    boolean downloadReport = false;//this is unreachable
    abc.interrupt();
    abc.stop();//error here!
}

少しでもお役に立てれば幸いです。

于 2013-10-29T18:43:14.597 に答える