我們在使用 java 中使用線程 Thread 的時候,在 run(){ } 里面的如果要傳遞參數給函數,一般,編譯系統都會提示我們,要將這個參數盡可能地設置為 final,即常量,一旦定義就不能再被修改的。
這樣的要求真是極好的!
除了定義為 final 就不能傳了嗎?非也,我們可以把 需要傳遞的變量弄為 global 全局的,但是!!問題往往就是這樣出現了。
大家看下下面這段代碼。
1 for(int u=0;u<result.length;u++){ 2 final int picIndex=u; 3 final Bitmap bitmap = result[picIndex]; 4 new Thread(new Runnable() { 5 @Override 6 public void run() { 7 InternetHelper.uploadPic 8 ( // 批量 上傳 圖片,此靜態函數 必須要 加 synchronized 9 "http://zzzzzzzz.php?"+"account="+userAccountTemp+"&postid="+userPostId, 10 bitmap, //修改之前這里直接用 result[u] 11 ""+picIndex+".jpg" //修改之前,picIndex 是全局的 12 ); 13 } 14 }).start(); 15 }
這是我項目里面的真實代碼,目的是為了把 Bitmap數組 result 里面的bitmap轉為 jpg 傳遞到 服務器,就是上傳圖片,由於圖片不可能是 1張,而且較大,700K左右/張,這是已經盡力壓縮的情況了,所以需要多個線程來傳。
在還沒有把 picIndex、bitmap 弄為 final之前,說下我遇到的情況,result 里面總是有2張以上的不同圖片 bitmap 數據,按照道理,執行完上述代碼,共開了兩個+線程,上傳了兩張以上的不同的圖片。
但是,我在服務器里檢測的時候,發現總是只上傳了一張圖片,就是說我把同一張圖片,上傳了幾次!!然后我就開始打印 log 了,分別打印 u、和 bitmap.toString(),發現,在進入 線程之前,都是正常的,即不同。按道理我傳遞的也是不同的才對。uploadPic 函數是沒問題的。
想了下,我覺得是線程搞的鬼了,它在執行函數內的代碼時,還來不及執行完, for 循環已經進行完畢,那么 對應的 參數也就跟着變了,但是等 函數內代碼再去內存中取這個數的時候,就取到了 后面的。
於是乎,把會變得,要傳的參數,全改為 final,問題解決。