Servlet设计,并发访问字段

时间:2012-11-12 09:29:46

标签: oop design-patterns servlets concurrency reentrantreadwritelock

我有一般性的问题,请指教。

我有一个servlet。

此servlet具有私有字段。

私有字段是一种元数据(公共类Metadata {// bla-bla-bla})。

处理 GET 请求时,此元数据用于执行某些操作。

我想在同一个servlet中实现POST方法。用户上传文件和元数据字段已更新。

问题:使用一个servlet实例在sereval web-threads之间共享元数据对象的并发访问此私有字段。 POST方法操作(更新元数据对象)可能导致元数据不一致状态,并发GET请求可能会失败。

问题:在GET请求运行时更新元数据对象的最佳方法是什么?

虚拟解决方案

  1. 在每次GET请求期间,一开始

  2. 同步元数据对象并将其克隆到一个块中,然后将其释放。

  3. 并发GET请求与元数据对象的克隆版本一致。

  4. 在每个POST请求期间。

  5. Synchonize Metadata对象并更新其字段。

  6. 发布元数据对象。

  7. 请建议或批评。

1 个答案:

答案 0 :(得分:1)

使用同步方法设置和获取元数据类是可以的,但如果你有多个读者和(多)少写作者,你的网络应用可能会慢一点:

  

Java synchronized关键字用于获取对其的独占锁定   宾语。当线程获取对象的锁定以供读取时   或写入,其他线程必须等到该对象的锁定   释放。想象一下,有很多读者线程可以读取共享内容   数据频繁,只有一个更新共享数据的编写器线程。   没有必要专门锁定对共享数据的访问   读取是因为可以并行完成多个读取操作   除非有写操作。

(摘自那个不错的post

因此,在某些情况下,使用多读取单写策略可能会更好,如同在同一Java5 ReadWriteLock接口doc中所解释的那样:

  

读写锁允许更高级别的并发性   访问共享数据而不是互斥锁允许的数据。   它利用了这样一个事实,即一次只有一个线程(a   writer线程)可以修改共享数据,在很多情况下可以任意数量   线程可以同时读取数据(因此读取器线程)。在   理论上,使用a允许的并发性增加   读写锁定将导致使用性能的提高   互斥锁。在实践中,这种并发性的增加会   只有在多处理器上完全实现,然后才能实现   共享数据的访问模式是合适的。

     

读写锁是否会提高使用性能   互斥锁的取决于数据的频率   读取与被修改相比,读取和写入的持续时间   操作,以及对数据的争用 - 即数量   将尝试同时读取或写入数据的线程。对于   例如,最初填充数据和的集合   此后很少被修改,同时经常被搜查   (例如某种目录)是使用的理想候选者   读写锁。但是,如果更新变得频繁,那么   数据花费的大部分时间都是完全锁定的   很少,如果并发增加。此外,如果阅读   操作太短了读写锁的开销   实现(本质上比共同更复杂   排除锁定)可以控制执行成本,特别是尽可能多   读写锁实现仍然通过一个序列化所有线程   小部分代码。最终,只有剖析和测量才会   确定使用读写锁是否适合您的   应用

即用型实施是ReentrantReadWriteLock

请查看之前的post,获取有关如何使用它的精彩教程。