2014-07-01 120 views
0

下面是我的代碼。我正在通過線程填充大小爲3500000的列表。首先我通過一個線程填充列表。此線程將返回包含3500000項的字符串列表。多線程執行時間最小化

此過程需要5秒鐘才能執行。

然後,我創建了另一個線程,並將整個任務分爲兩部分,並將它們分配給線程。

第一個線程將填充1900000項目的字符串列表,第二個線程將返回(3500000-1900000 = 1600000)項目。這兩個過程並行運行。所以,應該花更少的時間。 但是,對於這種情況,總計算時間也是5秒。

請有人幫我找出我做錯了什麼?

我非常需要最小化執行時間。我怎樣才能最小化時間?

package callablefutures; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 
import java.util.Calendar; 
import java.util.concurrent.TimeUnit; 
import java.util.Date; 

public class CallableFutures { 

    private static final int NTHREDS = 10; 
    public static void main(String[] args) { 

    ExecutorService executor = Executors.newFixedThreadPool(NTHREDS); 
    List<Future<List<String>>> list = new ArrayList<Future<List<String>>>(); 


    List<List<String>> lst=new ArrayList(); 
    List<String> list1=new ArrayList(); 
    List<String> list2=new ArrayList(); 


    Runtime rt = Runtime.getRuntime(); 
    long prevFree = rt.freeMemory(); 
    long startTime=System.currentTimeMillis(); 


     Callable<List<String>> worker = new MyCallable(list1,0,1900000); 
     Future<List<String>> submit = executor.submit(worker); 
     list.add(submit); 

     Callable<List<String>> worker1 = new MyCallable(list2,1900000,3500000); 
     Future<List<String>> submit1 = executor.submit(worker1); 
     list.add(submit1); 

    long sum = 0; 
    System.out.println(list.size()); 

    for (Future<List<String>> future : list) { 
     try { 
      lst.add(future.get()); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } catch (ExecutionException e) { 
     e.printStackTrace(); 
     } 
    } 
    executor.shutdown(); 
    long endTime=System.currentTimeMillis(); 
    System.out.println("Total Time Taken: " + (endTime-startTime)/1000%60 +" Seconds"); 
    System.out.println("Total Memory Taken (MB): " + ((prevFree-rt.freeMemory())/1024)/1024); 
    } 
} 



package callablefutures; 
import java.util.concurrent.Callable; 
import java.util.List; 
import java.util.ArrayList; 

public class MyCallable implements Callable<List<String>>{ 
    public List<String> StrList=new ArrayList(); 
    public int sIndex,eIndex; 
    public MyCallable(List<String> oList,int si,int ei) 
    { 
     this.StrList=oList; 
     this.sIndex=si; 
     this.eIndex=ei; 
    } 
    @Override 
    public List<String> call() throws Exception { 

    for (int i = this.sIndex; i < this.eIndex; i++) { 
     this.StrList.add("ID "+i); 
    } 
    return this.StrList; 
    //return this.StrList; 
    } 

} 
+1

你的基準測試大多隻是分配內存 - 很可能它不會很好地擴展。你可以嘗試'新ArrayList(1900000)'預先分配至少列表,但我懷疑這會有很大幫助。在現代JVM中運行的基準測試代碼並不容易,而且你做錯了:http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Chris

回答

0

你正在創建大約128 MB的數據,這將是比你的L3緩存更大,所以你將力推數據到主內存,這通常是很容易與一個線程飽和。如果您希望線程同時運行,您希望每個線程都被限制爲256 KB(因爲它們每個都有自己的L2高速緩存,假設它們運行在不同的核心上),或者如果在同一個核心上,每個都需要128 KB。

+0

你能否給我提供一個java代碼示例,這樣我就可以真正看到應用多線程,執行時間可以減少......理論上我知道這是可能的,但實際上我無法生成它。請幫助我!謝謝。 – dpkkry

+0

更改您的程序以執行CPU密集型操作,而不是內存或IO無效操作,例如通過遞歸計算斐波那契數。 (顯然,迭代速度要快得多,但作爲例子) –