Let's say you have the following class:
class A {
private Foo foo = new Foo();
Foo getFoo() {
return foo; //foo.clone()?
}
void modifyFoo() {
//modify this.foo
//...
}
}
I want to allow:
getFoo()
modifyFoo()
,getFoo()
calls arriving after that may be executed, until modification is done.Are there classes already for this problem in Java or do I have to implement it? If I have to implement it, then how do I implement it ensure thread safety?
It sounds like what you're looking for is a Read-Write lock, fortunately, java provides one, ReentrantReadWriteLock
. You can use it as follows:
class A {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private Foo foo = new Foo();
Foo getFoo() {
lock.readLock().lock();
try {
Foo tmp = foo; //foo.clone()?
} finally {
lock.readLock().unlock();
}
return tmp;
}
void modifyFoo() {
lock.writeLock().lock();
try {
//modify this.foo
//...
} finally {
lock.writeLock().unlock();
}
}
}
This will allow any number of threads to call getFoo()
simultaneously, but only one to call modifyFoo()
. When modify foo is called, the thread will block until all read locks are released, then begin executing and prevent any new read locks from being acquired until it has finished. There are still concurrency issues to consider since the returned Foo
can be modified by the code that calls getFoo
, but this should provide the basic tool you need.
You should use a ReentrantReadWriteLock. Multiple threads can read, one thread can write which blocks all reads.
class A {
private volatile Foo foo = new Foo();
Foo getFoo() {
return foo; //foo.clone()?
}
void synchronized modifyFoo() {
//modify this.foo
//...
}
}
The synchronized
keyword ensures that modifyFoo()
is atomic, that is, won't allow multiple threads to invoke it at once.
The volatile
keyword ensures that reads to foo
do not return a cached version (which could have been outdated if another thread modified it) and instead returns the current, correct value.
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