【发布时间】:2014-06-18 17:51:58
【问题描述】:
我需要在 Spring MVC 控制器中创建一个同步块,我想在其中使用 @PathVariable 作为我的同步对象。
@RequestMapping(value = "/upload/{providerId}/{contractId}", method = RequestMethod.POST, headers = "content-type!=multipart/form-data")
public void uploadChunked(
@PathVariable final long providerId,
@PathVariable final Long contractId ) {
Attachment attachment = new Attachment();
// store the attachment
synchronized( contractId ){
contractService.addAttachment( providerId, contractId, attachment );
}
}
我将 contractId 自动装箱到 Long 并将其用于同步对象,但是如果我在其他地方针对自动装箱的 Long 创建另一个同步块,则在自动装箱值上同步可能会成为问题。根据JLS 5.1.7
理想情况下,装箱一个给定的原始值 p,总是会产生一个 相同的参考。在实践中,这可能不可行 现有的实现技术。
因此,此块可能正在等待盒装 Long 上完全不相关的同步块完成,这是不可接受的。
但是,鉴于控制器本质上是一个单例,我如何安全地与 contractId 同步?需要明确的是,只有对具有相同 contractId 的此方法的调用必须同步 - 具有不同 contractIds 的调用可以同时运行。
我一直找不到任何现有的库来提供这种简单的支持。没有创建我自己的 util lib/class(例如:静态并发 hashmap 来存储 contractId 的锁定对象),还有其他更清洁的解决方案吗?
【问题讨论】:
标签: java multithreading spring synchronization