Assuming that readers = 10 x writers, which of the following solutions is better in terms of throughput. Which solution is better to use in production code?
- Using single lock for set operation and volatile variable for get operation
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public final class InstanceProvider {
private final Lock wLock = new ReentrantLock();
private volatile List<Instance> instances;
public void setInstances(List<Instance> newInstances) {
wLock.lock();
try {
doSmthWith(newInstances);
instances = newInstances;
} finally {
wLock.unlock();
}
}
public List<Instance> getInstances() {
return instances;
}
@Getter
public static final class Instance {
private final String name;
public Instance(String name) {
this.name = name;
}
}
}
- Using single read-write lock for both set and get operations
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public final class InstanceProvider {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private List<Instance> instances;
public void setInstances(List<Instance> newInstances) {
lock.writeLock().lock();
try {
doSmthWith(newInstances);
instances = newInstances;
} finally {
lock.writeLock().unlock();
}
}
public List<Instance> getInstances() {
lock.readLock().lock();
try {
return instances;
} finally {
lock.readLock().unlock();
}
}
@Getter
public static final class Instance {
private final String name;
public Instance(String name) {
this.name = name;
}
}
}
My assumption is that reading volatile is cheaper(basically it will be cached most of the time) and locks require additional instructions to be executed
volatileis all you need here.doSmthWith()do? Does it modify the list? Why does it need to be synchronized?setInstanceshas a reference to the list and so will every caller ofgetInstances(). Everyone could modify the list and hence, break everything. It’s also misleading to call this classInstanceProvider; it does not provide instances, it merely maintains a list of instances provided by someone else.