Addev
Addev

Reputation: 32243

Java wait for an object in another thread

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

Answers (1)

Gray
Gray

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

Related Questions