Java在另一个线程中等待一个对象

Add*_*dev 0 java multithreading android thread-safety

对于以下示例:

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;
}
Run Code Online (Sandbox Code Playgroud)

例如,两个线程同时调用getCar(2)时出现问题.然后两个线程都到达POINT A,并生成Car#2的两个实例.如何让第二个线程在POINT A等待,直到第一个线程完成创建,然后在两个调用中返回相同的对象?(我在Android中这样做)

谢谢

Gra*_*ray 6

正确的方法是在synchronized某处添加一个部分,以确保只有一个线程可以同时进入该块.

你特意问了一下,POINT A所以你可以让它createCarWithId同步.

public synchronized Car createCarWithId(int id){
Run Code Online (Sandbox Code Playgroud)

这将锁定this具有该方法的Object.这是关于synchronized方法的一些文档.

但是,您需要保护Car缓存的添加在缓存中找到它,因为多个线程将同时使用缓存.出于这个原因,你还需要制作findCarInCache synchronized.此外,由于您不想锁定两次getCar,它也可能是synchronized:

public synchronized Car getCar(int id){
...
public synchronized Car findCarInCache(int id){
...
public synchronized Car createCarWithId(int id){
Run Code Online (Sandbox Code Playgroud)

如果要减小锁定范围,可以创建一个可以使用的锁定对象synchronize:

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) {
      ...
   }
}
Run Code Online (Sandbox Code Playgroud)

这里有关于锁定对象的更多文档.