2014-10-12 69 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)中使用最終變量來防止混淆,而這些變量只有一個值。