【问题标题】:Any gotchas using static inner classes in a multi threaded environment?在多线程环境中使用静态内部类的任何陷阱?
【发布时间】:2010-12-16 11:54:13
【问题描述】:

这是我第一次涉足多线程领域,我目前正在使用 Java 并发库实现一个解决方案。该代码本质上接受了许多服务请求,异步提交所有请求,并在所有服务完成后返回响应映射。我的代码如下所示:

public OuterClass {

  public IResponseMap sendAsynchronousRequests(IRequest... dataList) {
    List<RepositoryFutureTask<IRequest>> futures = new ArrayList<RepositoryFutureTask<IRequest>>();

    //create one future for each request in the list
    for (final IRequest request : dataList) {
        RepositoryFutureTask<IRequest> future = new RepositoryFutureTask<IRequest>(request.getId(), new Callable<IRequest>() {
            public IResponse call() {
                return request.getService().callService(request.getRequestData());
            }
        });
        futures.add(future);
    }

   //Submit each future for execution
   for(Future future:futures) {
      //Singleton ReqeustExecutorService maintains a pool of threads via
      // java.util.concurrent.ExecutorService
      RequestExecutorService.execute(future);
   }

   //Block processing until all requests have finished and add responses to map
   //based on id as they finish
   IResponseMap responseMap = new ResponseMap();
   for(RepositoryFutureTask future:futures) {
      responseMap.put(future.getId(), future.get());
   }


    return responseMap;
  }

static class RepositoryFutureTask extends FutureTask<IResponse> {
     private String id;

    public RepositoryFutureTask(String theId, Callable<IResponse> callable) {
        super(callable);
          id = theId;
    }
    //standard getter for id omitted for conciseness
}
}

我主要感兴趣的是我的静态内部类解决方案是否会在多线程环境中产生任何问题,但我也会对上述解决方案中的任何其他 cmets 感兴趣。请注意,上面的代码可能并不完美,因为它仍然有点伪代码,我已经对其进行了很多泛化。错误处理也已被删除。提前致谢。

【问题讨论】:

标签: java multithreading inner-classes


【解决方案1】:

不,静态内部类的加载方式与顶级类相同。参见 JLS 的 8.5.2 -- http://java.sun.com/docs/books/jls/third_edition/html/classes.html

【讨论】:

    【解决方案2】:

    如果你在一个静态嵌套类中有一个synchronized 静态方法,它会在外部类中锁定不同的对象。我真的会推荐在任何方法上使用 synchronized 修饰符,尤其是在静态方法上。

    更多匿名内部类的问题,this 上的锁会有所不同。即使你写synchronized (this) { 它也不是那么明显。我已经看过几次了。

    理论上我猜如果嵌套类静态初始化程序与外部嵌套类静态初始化程序并行运行,您可能会遇到麻烦。从技术上讲,这与在两个外部类中运行静态初始化器相同,但您更有可能与嵌套类存在循环依赖关系。

    【讨论】:

      【解决方案3】:

      使用静态内部类没有问题。唯一的问题是private String id; 不是final。设置为final,你就可以使用线程安全了;-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-13
        • 1970-01-01
        • 2013-05-20
        相关资源
        最近更新 更多