如何从 Web 服务访问共享资源?

Posted

技术标签:

【中文标题】如何从 Web 服务访问共享资源?【英文标题】:How to access shared resource from a Web Service? 【发布时间】:2014-05-28 21:58:22 【问题描述】:

我读到在 Java EE 中,Web 服务将为每个请求生成一个线程,因此我不必自己执行线程阻塞操作(例如数据库查询)。

如何通过这种线程调度方法正确访问共享资源?

例如如果我有一个SessionManager,其中包含User 对象的映射和一个loginUser() 方法以允许在JSF 上下文之外登录,我将如何防止竞争条件?我是只使用互斥体,还是 JavaEE 提供了解决此问题的方法?

【问题讨论】:

【参考方案1】:

Java EE 没有为您提供任何解决您自己资源的资源争用的方法;但是 Java 可以。

对于您的情况,使用ConcurrentHashMap 可以解决您的大部分问题。 ConcurrentHashMap 将保护您免受两个线程同时更新Map 的情况(在HashMap 中,这可能会引发异常)。它为您提供来自Map 接口的与HashMap 相同的方法,以及来自ConcurrentMap 接口的一些有用方法(例如replaceputIfAbsent)。对于大多数需求,此选项就足够了。

话虽如此,有时您可能需要使用synchronized 关键字,即使您使用的是ConcurrentHashMap。例如,假设您想将两个项目放入Map,但对您来说非常重要的是,当当前线程发出两个put时,没有其他线程会@来自地图的 987654335@ 或 put。换句话说,ConcurrentHashMap 仅单独隔离每个调用的访问;对于需要隔离以跨越多个调用的情况,请使用synchronized

编辑遵循@Arjan 的评论:如果您使用的是JavaEE 6.0 及更高版本,则可以将@Singleton@Lock 结合使用以达到类似的效果。

【讨论】:

>Java EE 没有为您提供任何解决方案 - 嗯,@Singleton 和 @Lock 呢?见docs.oracle.com/javaee/6/api/javax/ejb/Lock.html【参考方案2】:

如果你需要使用 Map 你可以使用 Concuurent HashMap.. Java 不会处理你想要手动创建的东西,比如网络服务器,它会保存用户的键值对和登录后的 sessionId 之类的东西,通常服务器可以做到..

无论如何这都不是问题。这个 ConcurrentHashMap 非常适合这些情况,它是线程安全的,并且比 HashTable 性能更高(它们的工作方式不同)

HashTable 锁定 Map ConcurrentHashMap 自己锁定 evrey 项目。因此,如果两个线程没有接触相同的节点,则它们可以一起使用地图。..

您应该阅读以下内容: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html

希望有帮助

【讨论】:

我们希望允许从原生 android App 登录,所以我们不能使用 @SessionScoped @ManagedBeans。 知道了。您可以生成自己的 sessionId,一旦用户登录,您将 userId 和您的 SessionId 保存在此地图中。如果您从地图中删除用户注销...并且如果用户以不正确的方式关闭应用程序,您可以设置计时器并检查最后一次操作是否在 15 分钟之前完成,以便您自动从登录地图中删除该用户 请记住,如果你有一些集群环境。这不是最好的解决方案,你需要阅读一些关于 redis 的内容。它们提供缓存能力。检查这个链接@987654322 @ 我了解,但系统不会那么大。谢谢。

以上是关于如何从 Web 服务访问共享资源?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复访问被拒绝路径错误asp.net应用程序访问网络共享

如何从 JAX-WS Web 服务中访问 ServletContext?

NodeJS 应用程序如何使用 HTTP 请求从禁用的 CORS(跨域共享)服务器访问资源?

什么是跨域?如何实现跨域访问?

从基于 Sharepoint 声明的身份验证 Web 应用程序中的代码访问 Windows 共享

干货 | 玩转云文件存储——利用CFS实现web应用的共享访问