我读到在Java EE中,Web服务将为每个请求生成一个线程,所以我不必自己进行线程阻塞操作(例如数据库查询)。
如何从这种线程调度方法正确访问共享资源?
e.g。如果我有SessionManager
包含User
个对象的地图和loginUser()
方法以允许在JSF上下文之外登录,我将如何防止竞争条件?我只是使用互斥锁,还是JavaEE为这个问题提供了解决方案?
答案 0 :(得分:1)
如果您需要使用Map,可以使用Concuurent HashMap .. Java不会处理你想要手动创建的东西,它会保存用户的密钥值对,以及登录后的sessionId,通常服务器可以做到这一点。
无论如何这不是问题..这个ConcurrentHashMap非常适合那些情况,它是线程安全的,它的性能比HashTable高(它们工作得很差)
HashTable锁定Map ConcurrentHashMap自己锁定evrey项目。所以如果两个线程没有触及相同的节点,它们可以一起使用地图..
你应该读到这个: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html
希望有所帮助
答案 1 :(得分:1)
Java EE没有为您提供有关您自己资源的资源争用的任何解决方案;但Java确实如此。
对于您的情况,使用ConcurrentHashMap
可以解决您的大部分问题。 ConcurrentHashMap
将保护您免受两个线程在完全相同的时间内更新Map
的情况(在HashMap
中,可能会引发异常)。它为Map
接口提供了与HashMap
相同的方法,以及ConcurrentMap
界面中的一些有用方法(例如replace
和putIfAbsent
)。对于大多数需求,此选项就足够了。
尽管如此,有时候,即使您使用synchronized
,也可能需要使用ConcurrentHashMap
关键字。例如,考虑一下您希望将两个项目放入Map
的情况,但对您来说非常重要,而当前的帖子正在发布两个put
s,地图中没有其他帖子get
或put
。换句话说,ConcurrentHashMap
仅隔离每个呼叫的访问权限;对于需要隔离以跨越多个呼叫的情况,请使用synchronized
。
@Singleton
与@Lock
结合使用来实现类似的效果。