带有变量放置的Java Thread问题

时间:2014-10-12 01:07:27

标签: java

我尝试在10个线程并发Java线程上运行从一个到上限函数的简单求和。我当前的主要问题是为upperBound,lowerBound,sum和i设置变量。我想捕获i变量更新总和计算,但我得到错误"局部变量需要被声明为final。"我是Java的初学者,但是从我读过的关于声明变量final的内容来看,它是保持变量不可修改的 - 而不是我的目标......正确吗?

public class threads {
    public static void main(String[] args) {
    System.out.println(Thread.currentThread().getName());
    for(int i = 0; i < 10; i++) {
        new Thread("" + i) {
            public void run() {
                int sum = 0;
                int upperBound = 22;
                int lowerBound = 1;
                long threadID = Thread.currentThread().getId();
                for (int number = lowerBound; number <= upperBound; number++){
                    sum = sum + number + i;
                }
                System.out.println("Thread: " + threadID + " is running now and will compute the sum from 1 to " + (upperBound + i));
                System.out.println("Thread id " + threadID + " computes sum " + sum);
             }
           }.start();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

是的,声明i变量final以便您可以在匿名Thread子类中使用它将阻止您修改它。但你可以用i的当前值创建另一个变量并做出最终结果:

for (int i = 0; i < 10; i++) {
    final int iCopy = i;
    /* use iCopy in the Thread subclass */
}

当然,如果你需要在内部类体中有一个可变的iCopy(在这种情况下你不是,但一般情况下你可能),你必须制作一个(非最终的)副本在班上iCopy

这可能看起来很烦人,但是Java试图在这里帮助你:如果你可以在另一个线程中使用i,它应该看到i的值 - 实例化内部类时的值(隐式副本),或者线程实际运行时的值(循环结束后为10)?许多带闭包的语言选择后者的解释。 Java设计者决定只让你在内部类(和lambdas)中使用最终变量来防止混淆,内部类只有一个值。

答案 1 :(得分:0)

您在public void run(){...}方法中访问的变量应该声明为final,作为java创建的安全措施。在为一个变量赋值后,不能重新赋值。您还可以在GLOBAL方法中使用run变量(推荐),因为它可以在run方法中再次重新赋值。在您的情况下,变量i必须全局声明或声明为最终变量,或者在每个循环中任何其他最终变量应等于i。您的工作代码将是: -

for(int i = 0; i < 10; i++) {
    final int FINAL_I = i;
    new Thread("" + FINAL_I) {
        public void run() {
            int sum = 0;
            int upperBound = 22;
            int lowerBound = 1;
            long threadID = Thread.currentThread().getId();
            for (int number = lowerBound; number <= upperBound; number++){
                sum = sum + number + FINAL_I;
            }
            System.out.println("Thread: " + threadID + " is running now and will compute the sum from 1 to " + (upperBound + FINAL_I));
            System.out.println("Thread id " + threadID + " computes sum " + sum);
         }
       }.start();
    }
}

您也可以使用: -

for(int i = 0; i < 10; i++) {
    new Thread("" + i) {
        int i = this.i;
        public void run() {
            int sum = 0;
            int upperBound = 22;
            int lowerBound = 1;
            long threadID = Thread.currentThread().getId();
            for (int number = lowerBound; number <= upperBound; number++){
                sum = sum + number + i;
            }
            System.out.println("Thread: " + threadID + " is running now and will compute the sum from 1 to " + (upperBound + i));
            System.out.println("Thread id " + threadID + " computes sum " + sum);
         }
       }.start();
    }
}