8

シングルトン クラス (@Service 注釈付き) があります。このクラスには、実行に 200/300 ミリ秒かかるメソッドがあります。

このメソッドには @Cacheable アノテーションが付けられ、同期されます。

@Cacheable(value="nextPlaying", key = "#startingFrom.getYear() + #startingFrom.getMonth() + #startingFrom.getDay() + #startingFrom.getHours() + #startingFrom.getMinutes() + #locale.getLanguage()")
public synchronized List<Match> getNextPlaying(Date startingFrom, Locale locale)

このメソッドを呼び出す複数のスレッドを起動すると、結果がキャッシュされなくなるまで、これらの 200/300 ミリ秒の間、キャッシュされるまでメソッドが何度も実行されることがわかります。@Cacheable アノテーションは同期を考慮していないようです...これはバグですか?

4

2 に答える 2

30

良いニュースです。Spring Framework 4.3 は、@Cacheable に sync=true を追加することで、ニーズをサポートする方法を提供しました。

于 2016-09-12T03:24:54.127 に答える
12

@Cacheable アノテーションを使用する場合、キャッシュ検索を実装するコードはメソッドの外部にあります。したがって、同期修飾子は影響しません。

すべてのスレッドでキャッシュされた結果を使用する場合は、呼び出しをキャッシュ可能な getNextPlaying メソッドにラップする同期メソッドを作成する必要があります。このようなもの:

public synchronized List<Match> getNextPlayingSynchronized(Date startingFrom, Locale locale){
     return getNextPlaying(Date startingFrom, Locale locale);
}
...
@Cacheable(value="nextPlaying", key = "#startingFrom.getYear() + #startingFrom.getMonth() + #startingFrom.getDay() + #startingFrom.getHours() + #startingFrom.getMinutes() + #locale.getLanguage()")
public List<Match> getNextPlaying(Date startingFrom, Locale locale){
...//your old method without the synchronized modifier
}

これらのメソッドが異なるクラスにあることが重要です。そうしないと、アスペクトは機能しません。

于 2015-03-05T17:04:33.500 に答える