0

次の例では:

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;
}

たとえば、2 つのスレッドが同時に getCar(2) を呼び出すと、問題が発生します。その後、両方のスレッドが POINT A に到達し、Car#2 のインスタンスが 2 つ生成されます。最初のスレッドが作成を終了し、両方の呼び出しで同じオブジェクトを返すまで、2 番目のスレッドを POINT A で待機させるにはどうすればよいですか? (私はAndroidでこれをやっています)

ありがとう

4

1 に答える 1

6

正しい方法はsynchronized、同時に 1 つのスレッドのみがブロックに入ることができるようにするセクションをどこかに追加することです。

同期 POINT Aできるようにするために具体的に尋ねました。createCarWithId

public synchronized Car createCarWithId(int id){

thisこれにより、そのメソッドを持つオブジェクトがロックされます。synchronizedメソッドに関するドキュメントを次に示します。

ただし、複数のスレッドがキャッシュを同時に使用するため、キャッシュへの追加とCarキャッシュ内の検索の両方を保護する必要があります。このため、 も作成する必要がありますfindCarInCache synchronized。また、 で 2 度ロックしたくないので、getCarおそらく次のようにする必要がありますsynchronized

public synchronized Car getCar(int id){
...
public synchronized Car findCarInCache(int id){
...
public synchronized Car createCarWithId(int id){

ロックのスコープを縮小したい場合は、別の方法として、次のようなロック オブジェクトを作成できます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) {
      ...
   }
}

ロックオブジェクトに関するその他のドキュメントはこちらです。

于 2012-04-30T16:08:38.677 に答える