[英]java.util.concurrent multi-threading
我最近開始弄亂java.util.concurrent,希望有人指出我的代碼有缺陷或不良習慣。
程序將運行直到達到超時,然后輸出所有已完成的任務。
主班
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;
}
}
執行程序對此集合所做的所有工作都將對其進行迭代,並將它們添加到其自己的隊列中。 因此,幾乎任何集合都應該執行此操作(如果您有成千上萬的任務,並且使用的集合迭代成本很高,那么也許這可能是一個問題,但這是非常罕見的情況!)。
我認為您選擇的課程/方法很好。 想不到一個更合適的班級。 確實沒有“線程安全性更高”的類。 東西是否是線程安全的。 最多有些類使編寫線程安全程序更容易。 在這種情況下,我認為您正在使用適當的抽象級別。
(1)您應避免使用像害蟲這樣的成員字段,並盡可能使用局部變量。 在這種情況下,可以將result
設為局部變量,因此應該這樣做。 當必須使用成員字段時,您應該盡力使它們不變。 在這種情況下,通過將ID
和n
都設置為最終字段,它們可以是不可變的。
(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.