I have a Java class that is used in a multithreading application. Concurrent access is very likely. Multiple concurrent read operations should not block so I'm using a ReadWrite lock.
class Example {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private int i;
private boolean b;
public int getI() {
lock.readLock().lock();
final int tmp = i;
lock.readLock().unlock(),
return tmp;
}
public void setI( final int i ) {
lock.writeLock().lock();
this.i = i;
lock.writeLock().unlock();
}
public boolean getB() {
lock.readLock().lock();
final boolean tmp = b;
lock.readLock().unlock(),
return tmp;
}
public void setB( final boolean b ) {
lock.writeLock().lock();
this.b = b;
lock.writeLock().unlock();
}
}
For simplicity I left out the try...finally
blocks around the locks in this example.
I'm wondering if it's necessary (or let's say recommended) to lock/synchronize getters and setters of primitive types? I know that assign and return operations in Java are atomic. However by using these locks don't I make sure that every accessor gets the latest value (equals to using volatile
)?
What if the primitives were double
or long
?
It depends.
Note, however, that usually you need to synchronize operations at more coarse-grained level, for example, this:
Example e = ...;
synchronized (e) {
e.setI(e.getI() + 10);
}
For such scenarios your internal locks are redundant. Therefore perhaps it would be better to apply external synchronization where you use these objects, rather than internal synchronization.