我有一般性的问题,请指教。
我有一个servlet。
此servlet具有私有字段。
私有字段是一种元数据(公共类Metadata {// bla-bla-bla})。
处理 GET 请求时,此元数据用于执行某些操作。
我想在同一个servlet中实现POST方法。用户上传文件和元数据字段已更新。
问题:使用一个servlet实例在sereval web-threads之间共享元数据对象的并发访问此私有字段。 POST方法操作(更新元数据对象)可能导致元数据不一致状态,并发GET请求可能会失败。
问题:在GET请求运行时更新元数据对象的最佳方法是什么?
虚拟解决方案:
在每次GET请求期间,一开始
同步元数据对象并将其克隆到一个块中,然后将其释放。
并发GET请求与元数据对象的克隆版本一致。
在每个POST请求期间。
Synchonize Metadata对象并更新其字段。
发布元数据对象。
请建议或批评。
答案 0 :(得分:1)
使用同步方法设置和获取元数据类是可以的,但如果你有多个读者和(多)少写作者,你的网络应用可能会慢一点:
Java synchronized关键字用于获取对其的独占锁定 宾语。当线程获取对象的锁定以供读取时 或写入,其他线程必须等到该对象的锁定 释放。想象一下,有很多读者线程可以读取共享内容 数据频繁,只有一个更新共享数据的编写器线程。 没有必要专门锁定对共享数据的访问 读取是因为可以并行完成多个读取操作 除非有写操作。
(摘自那个不错的post)
因此,在某些情况下,使用多读取单写策略可能会更好,如同在同一Java5 ReadWriteLock接口doc中所解释的那样:
读写锁允许更高级别的并发性 访问共享数据而不是互斥锁允许的数据。 它利用了这样一个事实,即一次只有一个线程(a writer线程)可以修改共享数据,在很多情况下可以任意数量 线程可以同时读取数据(因此读取器线程)。在 理论上,使用a允许的并发性增加 读写锁定将导致使用性能的提高 互斥锁。在实践中,这种并发性的增加会 只有在多处理器上完全实现,然后才能实现 共享数据的访问模式是合适的。
读写锁是否会提高使用性能 互斥锁的取决于数据的频率 读取与被修改相比,读取和写入的持续时间 操作,以及对数据的争用 - 即数量 将尝试同时读取或写入数据的线程。对于 例如,最初填充数据和的集合 此后很少被修改,同时经常被搜查 (例如某种目录)是使用的理想候选者 读写锁。但是,如果更新变得频繁,那么 数据花费的大部分时间都是完全锁定的 很少,如果并发增加。此外,如果阅读 操作太短了读写锁的开销 实现(本质上比共同更复杂 排除锁定)可以控制执行成本,特别是尽可能多 读写锁实现仍然通过一个序列化所有线程 小部分代码。最终,只有剖析和测量才会 确定使用读写锁是否适合您的 应用
即用型实施是ReentrantReadWriteLock。
请查看之前的post,获取有关如何使用它的精彩教程。