2014-10-12 45 views
0

我想在10个线程并发Java线程上从一个运行一个简单的总和到上限功能。我目前的主要问题是放置upperBound,lowerBound,sum和i的变量。我想捕捉我变量更新总和计算,但我得到的错误“局部变量需要宣布最终。”我是Java的初学者,但从我读过的关于声明变量final的内容来看,它是否使变量无法修改 - 不是我的目标......对吧?变量放置的Java线程问题

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(); 
     } 
    } 
} 

回答

0

您在public void run(){...}方法中访问的变量应声明为final作为由java创建的安全措施。最后一个变量在赋值后不能被赋值。您也可以在run方法(建议)中使用GLOBAL变量,因为它可以在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(); 
    } 
} 
0

是的,声明i变量final,因此您可以在匿名Thread子类中使用它,这将阻止您修改它。但是你可以只是做与我的当前值另一个变量并作出最后:

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

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

这似乎很烦人,但Java试图帮助你:如果你可以在其他线程中使用i,它应该看到什么值i - 内部类实例化时的值(隐式副本),还是线程实际运行时的值(循环结束后为10)?许多关闭语言选择后一种解释。 Java设计者决定通过只让你在内部类(和lambda)中使用最终变量来防止混淆,而这些变量只有一个值。