在多线程环境中使用静态内部类有任何问题吗?
这是我第一次涉足多线程领域,目前我正在使用 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
}
}
我主要感兴趣的是我的静态内部类解决方案是否会在多线程环境中产生任何问题,但也会对上述解决方案的任何其他评论感兴趣。请注意,上面的代码可能并不完美,因为它仍然有些伪代码,而且我已经对其进行了很多泛化。错误处理也已被删除。提前致谢。
This is my first foray into multi threaded land and I'm currently implementing a solution using the Java concurrency library. The code essentially takes in a number of service requests, submits all the requests asynchronously and returns a map of responses when all services have completed. My code looks something like this:
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
}
}
I'm primarily interested if my static inner class solution will create any issues in a multi threaded enviroment, but would also be interested in any other comments on the above solution. Note that there's a chance the code above isn't perfect as its still somewhat pseudo code and I've generified it a lot. Error handling has also been removed. Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,静态内部类的加载方式与顶级类相同。请参阅 JLS 的 8.5.2 -- http://java.lang. sun.com/docs/books/jls/third_edition/html/classes.html
No, static inner classes are loaded in a manner equivalent to a top level classes. See 8.5.2 of the JLS -- http://java.sun.com/docs/books/jls/third_edition/html/classes.html
如果静态嵌套类中有一个
synchronized
静态方法,那么它将是对外部类中相同对象的不同对象的锁定。我真的会推荐在任何方法上使用synchronized
修饰符,特别是在静态方法上。更多关于匿名内部类的问题,
this
上的锁会有所不同。即使你写成synchronized (this) {
,它实际上也不是那么明显。我已经见过几次了。从理论上讲,我猜如果嵌套类静态初始化程序与外部嵌套类静态初始化程序并行运行,您可能会遇到麻烦。从技术上讲,这与在两个外部类中运行静态 intiailsers 相同,但您更有可能与嵌套类存在循环依赖关系。
If you have a
synchronized
static method in a static nested class, it will be a lock on a different object to the same in the outer class. I would really recommend thesynchronized
modifier on any method, and particularly on a static method.More a problem with anonymous inner classes, locks on
this
will be different. Even if you writesynchronized (this) {
it really isn't that obvious. I have seen it done a few times.Theoretically I guess you could potentially run into trouble if the nested class static initialiser ran in parallel to the outer nester class static initialiser. Technically this is the same as running static intiailsers in two outer classes, but you are more likely to have cyclic dependencies with nested classes.
使用静态内部类没有问题。唯一的问题是
private String id;
不是final
。将其设为final
,这样您就可以保证线程安全了;-)No issues with using static inner class. The only issues is that
private String id;
is notfinal
. Make itfinal
and you'll be alright with thread-safety ;-)