我正在使用一个单一的静态类来提供一个列表的多线程应用程序。 我希望静态类的getter方法可以自由地工作(彼此不同步),但当setter方法在工作时,我希望所有的getter方法都被锁定并等待setter方法完成任务。 我不想在同时调用getter方法时锁定它们,因为这会大大降低性能。 getter方法每天被调用1,000,000次,而setter方法只需要每天工作一次。
我正在使用一个单一的静态类来提供一个列表的多线程应用程序。 我希望静态类的getter方法可以自由地工作(彼此不同步),但当setter方法在工作时,我希望所有的getter方法都被锁定并等待setter方法完成任务。 我不想在同时调用getter方法时锁定它们,因为这会大大降低性能。 getter方法每天被调用1,000,000次,而setter方法只需要每天工作一次。
考虑使用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();
}
}
对于设置器方法同样如此,但使用readWriteLock.writeLock()
代替。
该类将拥有一个单独的ReentrantReadWriteLock
对象, 由每个对象上所有getter和setter共享(或者,如果您愿意,每个getter/setter对都有一个)。
这相当繁琐,但应该能提供良好的并发性能。出于这些原因,只有在真正需要时才应采用此方法,并且这意味着测量您仅使用普通同步时获得的并发性能下降。
synchronized
也可能不会增加足够的延迟。但每秒调用一百万次,就一定会有影响。
synchronized
本身的开销;相反,他只是不希望对getter的调用必须是顺序的。(我认为你是正确的,他不应该担心;但不用担心的原因是getter应该非常快和便宜,而不是因为synchronized
。) - ruakhsynchronized
的成本通常比调用 getter 方法要高得多。如果您的 getter 方法比这个花费更高,那么它就不是一个普通的 getter 方法。 - Peter Lawrey