0

Robin已经解决了这个问题。谢谢罗宾!

我想要做的背后的想法是制作一个每 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 需要分别声明为 final 一个,critical_requests 需要声明两个。

我该如何调和呢?

4

3 回答 3

2

查看您的代码,问题是变量wait_delaycritical_requests变量。

  1. 没有真正需要在ActionListener. Timer在它对延迟产生任何影响之前,您必须重新设置它Timer
  2. Timer每次更改变量时创建一个新对象wait_delay会产生很多Timer实例,Timer默认情况下每个实例都会重复运行。只有当你打电话setRepeats( 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

通常,您有两种选择:

  • 将其作为类字段。
  • 使用另一个变量并将旧变量分配给它,类似于:

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 回答