I am having a multi-thread application using a single static class which provides a list. I want getters of the static class to work freely (not synchronized against each other) but when a setter is working I want all getters to get locked and wait until setter's job is done. I don't want to lock getters when they are called together since it would degrade performance a lot. Getters are called 1,000,000 times per day and setter is only supposed to work once per day.
Consider using a java.util.concurrent.locks.ReadWriteLock
implementation, such as ReentrantReadWriteLock
(see javadoc)
A
ReadWriteLock
maintains a pair of associated locks, one for read-only operations and one for writing. The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.
You would use this instead of synchronized
. Your getters would obtain the read lock, then release when they return, e.g.
public String getX() {
Lock readLock = readWriteLock.readLock();
readLock.lock();
try {
return value;
} finally {
readLock.unlock();
}
}
Similarly for setters methods, but using readWriteLock.writeLock()
instead.
The class would have a single ReentrantReadWriteLock
object, shared by all getters and setters on each object (or, if you wish, one per getter/setter pair).
It's quite cumbersome, but should give good concurrency. For those reasons, you should only take this on if you really need it, and that means measuring the degraded concurrency you get if you just use vanilla synchronization.
Your setter can take a copy of the data on each update and getters can use the copy. This can be very expensive for the setter, but minimal impact for the getters.
However a synchronized lock can be in the order of 25 to 100 ns. Even if you calling a synchronized method one million times per minute, synchronized
may not add enough delay to worry about. At one million per second, it definitely will.
I would first synchronize all the accesses, and only optimize if that proves to be a performance problem.
To optimize, you could use a CopyOnWriteArrayList, or a ReadWriteLock. It's hard to give a definitive solution without knowing the context more precisely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With