3

一般的なアプローチについて支援を求めています。

buttonclickでメールボックスに未読メールがないかチェックするJavaコードを作成しました。

ここで、このコードをバックグラウンドで永続的に実行し、2分ごとにメールボックスをチェックする必要があります。

悪いアイデア:

while(true)
{
checkMails();
Thread.sleep(120000);
}

グラフィカルインターフェイスの残りの部分は明らかにフリーズするので、スレッドで何らかの魔法が発生する必要があると思います。

これはどのように実現できますか?

4

6 に答える 6

4

javax.swing.Timer、またはのいずれかを使用しますSwingWorkerが、後者はこのシナリオでは少しやり過ぎです。


このタスクで Swing コンポーネントが変更されない場合は、別のスレッドを生成してみませんか?

Thread t = new Thread(new Runnable(){
    @Override
    public void run(){
        while(!Thread.currentThread().isInterrupted()){
            //do stuff

            try{
                Thread.sleep(120000);
            }catch(InterruptedException e){
                Thread.currentThread().interrupt();
            }
        }
    }
});
t.start();

booleanボタンがクリックされるたびに新しいスレッドが生成される可能性があるため、おそらく a を使用してスレッドが一度だけ作成されるようにする必要があることに注意してください。これはおそらくあなたが望むものではありません。

于 2011-07-21T14:04:34.610 に答える
2

checkMails()を処理し、すでに持っているアクションを実行する別のスレッドを生成してみませんか。GUIを更新するときは注意してください。

    Thread thread = new Thread(new Runnable() {
        public void run() {

            while (true) {
                checkMails();
                Thread.sleep(120000);
            }
        }
    });

編集:たぶん、(何らかの理由で)新着メールのチェックを停止したい場合に備えて、どこかにチェックを追加する必要があります。また、あなたは電話する必要がありますthread.start();

于 2011-07-21T14:03:31.923 に答える
1

これを解決するには、スレッドを使用する必要があります。スレッドはマルチタスクのようなものです。

Thread t = new Thread(){
    public void run(){
        //do job
    }
}
t.start(); //starts the thread

スレッドを終了するには、何らかの停止条件が必要です

public boolean run = false;
Thread t = new Thread(){
    public void run(){
        while(run)
            //do job
    }
}
public void startThread(){
    t.start(); //starts the thread
}

以下も参照してください。

Thread.stop()スレッドを強制終了しますが、これは非常に悪いことです。たとえば、配列に書き込んでいるとします。

for(int i = 0; i < myAr.length; i++)
    myAr[i] = getStuff(i);

そして ati = 5Thread.stop()呼び出されます。あなたのプログラムは、すべてが正しいと思っているのに、実際にはそうではありません!

スレッドを強制終了するには、 に設定runfalseます。runboolean、2 番目の例で示したものです。もう 1 つのオプションは、Thread(インライン オーバーライド メソッドだけでなく) のサブクラスを作成し、メソッドhalt()( stopis final ) を作成することです。falsehalt()に設定されます。グローバルのままです。runrunboolean

その例を次に示します。

public class MyThread extends Thread {
    public boolean run = true;
    public void run(){
        run = true;
        while(run)
            doStuff();
    }
    public void halt(){
        run = false;
    }
}

2 つのスレッドが同じオブジェクトを一度に変更しないように注意する必要があります。オブジェクトを乱数ジェネレーターに変えるようなものです:/

スレッドの力を手に入れたあなたは、悪のためではなく善のために賢く使ってください! 進んでスレッドセーフになりましょう。

于 2011-07-21T14:10:45.733 に答える
1

を使用しjavax.swing.Timerます。このようなもの:

int delay = 120000;
ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        checkMails();
    }
};
new Timer(delay, taskPerformer).start();
于 2011-07-21T14:04:33.627 に答える
0

いくつかのアイデア:

1)java.util.Timer定期的に起動する を作成し、メールボックスのメッセージをチェックし、 を使用して GUI を更新しSwingUtilities#invokeLaterます。

2)メールボックスのチェックと GUI の更新の両方をスケジュールするタイマー ( または のいずれjava.util.Timerか) を作成します。javax.swing.Timerjavax.swing.SwingWorker

3)Threadメールボックスをチェックし、使用して GUI を更新し、SwingUtilities#invokeLaterしばらくスリープする を作成します。

タスクをキャンセルする必要がある場合はタイマーを停止できるため、1 または 2 を使用します。

于 2011-07-21T15:06:17.917 に答える
-1

checkMails() メソッドの終了後に UI を更新する必要がある場合は、明らかにEDTを使用する必要があります。

そして、非同期(他のものは同期)の方法を探しています。

確かにあなたはSwingUtilities.html#invokeLater(java.lang.Runnable)を探しています

私の知る限り、これは Swing のバックグラウンド タスクを実行する正しい方法です。

Runnable checkMail = new Runnable() {
    public void run() {
        while(true) {
            checkMails();
            Thread.sleep(120000); //but this is very naive approach to use sleep, consider using timer ;)
        }
    }
};

SwingUtilities.invokeLater(checkMail);

invokeLater(Runnable doRun): doRun.run() が AWT イベント ディスパッチ スレッドで非同期に実行されるようにします。

invokeAndWait(Runnable doRun): doRun.run() が AWT イベント ディスパッチ スレッドで同期的に実行されるようにします。

于 2011-07-21T14:21:22.900 に答える