簡體   English   中英

java.util.concurrent多線程

[英]java.util.concurrent multi-threading

我最近開始弄亂java.util.concurrent,希望有人指出我的代碼有缺陷或不良習慣。

程序將運行直到達到超時,然后輸出所有已完成的任務。

  • 在這種情況下,我應該使用ArrayList嗎?
  • 是否有更適合該任務的類,也許是線程安全的。
  • 任何建設性的批評都會有所幫助。

主班

public class ConcurrentPackageTests {

private final ExecutorService executor;

    public ConcurrentPackageTests() {
    executor = Executors.newFixedThreadPool(2);
    this.testCallable(4);
}

private void testCallable(int nInstances) {

    long startTime = System.currentTimeMillis();

    List<Future<Integer>>      futures = null;
    List<Integer>              results = null;
    ArrayList<exCallable>      callables = new ArrayList<exCallable>(nInstances);

    for (int id = 0; id < nInstances; id++) {callables.add(id, new exCallable(id,5));}  

    //get a list of the futures, monitor the futures outcome.
    try { futures = executor.invokeAll(callables, 5, TimeUnit.SECONDS);}
    catch (Exception e) { System.out.println("TIMED OUT");}

    executor.shutdown();    //Stop accepting tasks.

    System.out.println();

    results = getFValues(futures);  //gets all completed tasks
    printOutValues(results, startTime);

}

/**
 * get all integer values that terminated successfully.
 * @param e
 * @return Integer List of results
 */
private List<Integer> getFValues(List<Future<Integer>> e){
    final ArrayList<Integer> list = new ArrayList<Integer>(e.size());
    for (Future<Integer> f : e) {
        if(!f.isCancelled()){
            try {  list.add(f.get(1, TimeUnit.SECONDS));}
            catch (Exception e1) { System.out.println("Err");}      
        }
    }
    list.trimToSize();
    return list;
}

private void printOutValues(List<Integer> results, long startTime){
    for (Integer integer : results) {
        System.out.println("Result: " + integer);
    }   System.out.println("Time: "+ ( System.currentTimeMillis() - startTime ));
}

可召回

public class exCallable implements Callable<Integer>{

private int n;
int result = 1;
final int ID;

public int getResult() {
    return result;
}

public exCallable(int ID, int pN) {
    this.ID = ID;
    this.n = new Random().nextInt(pN)+ 1;
}

@Override
public Integer call() throws Exception{

    for (int i = 0; i < n; i++) {
        result *= 2;
        Thread.sleep(500);  //Simulate work.
    }

    System.out.println("Computation<" + ID + ">2^"+n+"="+result);
    return result;
}

}
  • 在這種情況下,我應該使用ArrayList嗎?

執行程序對此集合所做的所有工作都將對其進行迭代,並將它們添加到其自己的隊列中。 因此,幾乎任何集合都應該執行此操作(如果您有成千上萬的任務,並且使用的集合迭代成本很高,那么也許這可能是一個問題,但這是非常罕見的情況!)。

  • 是否有更適合該任務的類,也許是線程安全的。

我認為您選擇的課程/方法很好。 想不到一個更合適的班級。 確實沒有“線程安全性更高”的類。 東西是否是線程安全的。 最多有些類使編寫線程安全程序更容易。 在這種情況下,我認為您正在使用適當的抽象級別。

  • 任何建設性的批評都會有所幫助。

(1)您應避免使用像害蟲這樣的成員字段,並盡可能使用局部變量。 在這種情況下,可以將result設為局部變量,因此應該這樣做。 當必須使用成員字段時,您應該盡力使它們不變。 在這種情況下,通過將IDn都設置為最終字段,它們可以是不可變的。

(2)為每個任務創建一個新的Random對象是IMO的明智決定。 如果您願意,可以使用以下常見優化:

ThreadLocal<Random> rng = new ThreadLocal<Random>(){
    @Override
    protected Random init(){
        return new Random();
    }
}; 
// afterwards...
Random r = rng.get();

Random情況下,您可能不會收獲很多,但是當涉及昂貴的對象(例如JAXB解析器)時,此優化可能非常有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM