0

これはロビンによって解決されました。ロビンありがとう!

私がやりたいことの背後にある考え方は、X秒ごとにアクションを実行するタイマーを作成することですが、Xは使用ごとに変更する必要があります。

今、私はこのようにやっています:

 try {
        final FileWriter fstream = new FileWriter("timetest.log");
        final BufferedWriter out = new BufferedWriter(fstream);

        ActionListener task_performer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                critical_requests[0]++;
                try {
                    System.out.println("DEBUG: Critical Section requests: " + critical_requests[0] + "\n");
                    out.write("Critical Section request:\t" + critical_requests[0] + "\n");
                } catch (IOException e) {
                    System.out.println(e.getMessage() + "\n");
                }
                ((Timer)evt.getSource()).setDelay( 150 + (rand.nextInt(10) * time_unit ));
            }
        };
        new Timer(wait_delay, task_performer).start();
        System.out.println("Entering while loop\n");
        while(true) {
            if(critical_requests[0] >= 60){
                try {
                    out.close();
                } catch (IOException e) {
                    System.out.println("Close failed for some reason:\t" + e.getMessage() + "\n");
                    System.exit(-1);
                }
                System.exit(0);
            }
            //System.out.println("" + critical_requests[0] + "\n");    // Debug
            critical_requests[0] = critical_requests[0];    // Java is an insane language and it requires me to have this line here
        }
    } catch (IOException e) {
                System.out.println(e.getMessage());
                System.exit(-1);
    }

私が得るエラーは次のとおりです。

local variable is accessed from within inner class; needs to be declared final

それらのいくつかを最終的にしようとしましたが、リスナー内の値を変更できません。さらに、一部の変数はfinalにする意味がありません(BufferedWriter out、rand)。

5つのコンパイラエラーはすべて次のとおりです。ローカル変数randは内部クラス内からアクセスされます。out、rand、wait_delayの場合はそれぞれ最後に1つ、critical_requestsの場合は2つ宣言する必要があります。

どうすればこれを調整できますか?

4

3 に答える 3

2

コードを見ると、問題はwait_delaycritical_requests変数です。

  1. 内で変更する必要はありませんActionListenerTimerの遅延に影響を与える前に、もう一度オンに設定する必要がありますTimer
  2. 変数Timerを変更するたびに新しいオブジェクトを作成すると、多くのインスタンスが生成され、それぞれがデフォルトで繰り返しとして実行され続けます。あなたが電話した場合にのみ、彼らは実際に停止します。あなたのコメント(質問の一部であるはずです)を見て、あなたはの遅延を更新したいと思いますwait_delayTimerTimersetRepeats( false )Timer
  3. critical_requests内の変数を本当に変更する必要ActionListenerがある場合は、最終的な配列に格納できます

だから私はあなたのコードを次のようなものに変更することをお勧めします

final int[] critical_requests = new int[]{ 0 };
final Outputstream out = ...;
ActionListener task_performer = new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            critical_requests[0] = critical_requests[0] + 1;
            try {
                out.write("Critical Section request:\t" + (critical_requests[0]) + "\n");
                ((Timer)evt.getSource()).setDelay( 10 + (rand.nextInt() % 10) );
            } catch (IOException e) {
                System.out.println(e.getMessage());
                System.exit(-1);
            }
        }
};
Timer the_one_and_only_timer = new Timer( wait_delay, task_performer );
于 2012-10-14T07:50:52.523 に答える
1

通常、2つのオプションがあります。

  • クラスフィールドとして作成します。
  • 別の変数を使用し、それに古い変数を割り当てます。次のようになります。

ActionListener task_performer = new ActionListener()
{
    public void actionPerformed(ActionEvent evt)
    {
        int temp = wait_delay; // assuming wait_delay is final
        temp = ...;
于 2012-10-14T07:31:23.087 に答える
1

メソッドで「wait_delay」を非ローカル変数にします。メソッド定義から外します。

于 2012-10-14T07:32:29.300 に答える