繁体   English   中英

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

[英]How can I synchronize getter while a setter is working in Java

我正在使用一个提供列表的静态类的多线程应用程序。 我希望静态类的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也可能无法增加足够的延迟来担心。 每秒100万,肯定会。

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

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

这是使用CopyOnWriteArrayList的典型案例。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM