当setter在Java中工作时,如何同步getter

我正在使用一个提供列表的单个静态类的multithreading应用程序。 我希望静态类的getter能够自由地工作(彼此不同步)但是当setter工作时我希望所有的getter都被锁定并等到setter的工作完成。 我不想在调用它们时锁定getter,因为它会大大降低性能。 吸气剂每天被称为1,000,000次,而且每天只能使用一次。

考虑使用java.util.concurrent.locks.ReadWriteLock实现,例如ReentrantReadWriteLock (请参阅javadoc )

ReadWriteLock维护一对关联的锁,一个用于只读操作,另一个用于写入。 只要没有写入器,读锁定可以由多个读取器线程同时保持。 写锁是独占的。

您可以使用此而不是synchronized 。 你的getter将获得读锁定,然后在返回时释放,例如

 public String getX() { Lock readLock = readWriteLock.readLock(); readLock.lock(); try { return value; } finally { readLock.unlock(); } } 

类似于setter方法,但改为使用readWriteLock.writeLock()

该类将有一个ReentrantReadWriteLock对象,由每个对象上的所有getter和setter共享(或者,如果您愿意,每个getter / setter对一个)。

它非常麻烦,但应该提供良好的并发性。 出于这些原因,如果您真的需要它,您应该只接受它,这意味着如果您只是使用vanilla同步,那么测量降级的并发性。

您的setter可以在每次更新时获取数据的副本,并且getter可以使用该副本。 对于设定者来说这可能非常昂贵,但对吸气剂的影响很小。

然而,同步锁定可以是25到100ns的量级。 即使您每分钟调用一次同步方法一百万次, synchronized也可能无法增加足够的延迟来担心。 每秒一百万,肯定会。

我首先会同步所有访问,并且只有在certificate是性能问题时才进行优化。

要进行优化,可以使用CopyOnWriteArrayList或ReadWriteLock。 如果不更精确地了解上下文,很难给出明确的解决方案。

这是使用CopyOnWriteArrayList的典型案例。

“这通常成本太高,但是当遍历操作大大超过突变时,它可能比替代方法更有效,并且当你不能或不想同步遍历但需要排除并发线程之间的干扰时,它非常有用。”