首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.util.concurrent多线程

java.util.concurrent多线程
EN

Stack Overflow用户
提问于 2012-08-19 07:02:39
回答 1查看 379关注 0票数 0

我最近开始使用java.util.concurrent,我希望有人能指出我的代码中的缺陷或坏习惯。

程序运行到超时,然后输出所有已完成的任务。

  • 在这种情况下,我应该使用ArrayList吗?
  • 是否有一个更适合这个任务的更适合线程安全的类。
  • 任何建设性的批评都会有所帮助。

主班

代码语言:javascript
复制
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 ));
}

可赎回

代码语言:javascript
复制
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;
}

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-19 11:00:37

  • 在这种情况下,我应该使用ArrayList吗?

执行器对该集合所做的所有操作都是遍历它,并将它们添加到自己的队列中。因此,几乎所有的集合都应该这样做(如果您有数千个任务,并且使用一个非常昂贵的迭代集合,那么它可能是一个问题,但这是一个非常罕见的情况!)

  • 是否有一个更适合这个任务的更适合线程安全的类。

我认为你选择班级/方法是可以的。想不出更合适的课程了。没有真正的类是“更安全的线程”。东西要么是线程安全的,要么不是。最多有一些类可以使编写线程安全程序变得更容易。在这种情况下,我认为您需要一个适当的抽象级别。

  • 任何建设性的批评都会有所帮助。

(1)您应该避免像pest这样的成员字段,并尽可能使用局部变量。在这种情况下,您可以使result成为一个局部变量,所以您应该这样做。当您必须使用成员字段时,您应该非常努力地使它们成为不变的。在这种情况下,IDn都可以是不可变的,因为它们都是最终字段。

(2)为每个任务创建一个新的Random对象是一个很好的决策。如果您喜欢,可以使用以下常见优化:

代码语言:javascript
复制
ThreadLocal<Random> rng = new ThreadLocal<Random>(){
    @Override
    protected Random init(){
        return new Random();
    }
}; 
// afterwards...
Random r = rng.get();

Random的情况下,您可能不会获得很多,但是当涉及到昂贵的对象(例如JAXB解析器)时,这种优化可能会非常有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12024832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档