简体   繁体   中英

java.util.concurrent multi-threading

I recently started messing with the java.util.concurrent, and I would like if someone could point out flaws or bad habits in my code.

The program runs until a time out is reached, then outputs all the tasks that completed.

  • Should I be using ArrayList in this case?
  • Is there a better suited class for this task that is perhaps more thread safe.
  • Any constructive criticism would help.

Main Class

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 ));
}

Callable

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;
}

}
  • Should I be using ArrayList in this case?

All the executor does with this collection is iterate through it and add them to its own queue. Therefore almost any collection should do (should you have thousands of tasks and use a collection that is very costly to iterate, then maybe it could be a problem but that's a very rare situation!).

  • Is there a better suited class for this task that is perhaps more thread safe.

I think your choice of class/method is fine. Can't think of a better suited class. There aren't really classes that are "more thread safe". Stuff are either thread safe or not. At most there are classes that make coding thread safe programs easier. In this case I think you are going with a suitable level of abstraction.

  • Any constructive criticism would help.

(1) You should avoid member fields like the pest, and use local variables if at all possible. In this case, you can make result a local variable, so you should. When you have to use member fields, you should strive very hard to make them immutable. In this case, both ID and n can be immutable by making them both final fields.

(2) Creating a new Random object per task is a good decision IMO. If you feel like it, you can use this common optimization:

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

In case of Random you may not gain a lot, but this optimization can be highly effective when expensive objects (eg a JAXB parser) are involved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM