Reputation: 32243
For the following example:
public Car getCar(int id){
Car result= findCarInCache(id);
if (result==null){
// POINT A
return createCarWithId(id);
} else {
return result;
}
}
public Car findCarInCache(int id){
// Do something for find a car with this id in the cache
}
public void addToCache(Car car){
// Add the car to the cache
}
public Car createCarWithId(int id){
Thread.sleep(10000);
Car result= new Car(id);
addToCache(Car);
return result;
}
The problem comes when two Threads call at the same time getCar(2) for example. Then both threads reach the POINT A, and two instances of the Car#2 are generated. How can I make the second thread to wait at the POINT A, until the first thread finish the creation and then return the same object in both calls? (I'm doing this in Android)
Thanks
Upvotes: 0
Views: 1379
Reputation: 116908
The right way would be to add a synchronized
section somewhere which makes sure that only one thread can enter the block at the same time.
You asked specifically about POINT A
so you could make the createCarWithId
be synchronized.
public synchronized Car createCarWithId(int id){
This will lock on the this
of the Object who has that method. Here's some documentation on synchronized
methods.
However, you need to protect both the addition of the Car
to the cache and the finding it in the cache since multiple threads will be using the cache simultaneously. For this reason you also need to make the findCarInCache
synchronized
. Also, since you don't want to lock twice in getCar
, it should also probably be synchronized
:
public synchronized Car getCar(int id){
...
public synchronized Car findCarInCache(int id){
...
public synchronized Car createCarWithId(int id){
If you want to reduce the scope of your lock, as an alternative you can create a lock object that you can synchronize
on:
private final Object lockObject = new Object();
...
public Car getCar(int id){
synchronized (lock) {
...
}
}
public Car findCarInCache(int id){
synchronized (lock) {
...
}
}
public Car createCarWithId(int id){
synchronized (lock) {
...
}
}
Here's more documentation on lock objects.
Upvotes: 6