protected synchronized boolean isTimeoutOccured(Duration timeoutDuration) {
DateTime now = new DateTime();
if (timeoutOccured == false) {
if (new Duration(requestTime.getMillis(), now.getMillis()).compareTo(timeoutDuration) > 0) {
timeoutOccured = true;
}
}
return timeoutOccured;
}
protected boolean isTimeoutOccured2(Duration timeoutDuration) {
return atomicTimeOut.compareAndSet(false, new Duration(requestTime.getMillis(), new DateTime().getMillis()).compareTo(timeoutDuration) > 0);
}
Répondre
Il convient de noter que l'expression booléenne
new Duration(requestTime.getMillis(), new DateTime().getMillis()).compareTo(timeoutDuration) > 0
se trouve dans un bloc synchronisé dans votre premier exemple, mais en dehors de toute barrière de mémoire dans le second. (Dans le second exemple, le résultat de l'expression est passé en argument à l'appel atomique compareAndSet, mais l'évaluation de l'expression elle-même se produit en dehors de toute barrière de mémoire.)
Par conséquent, la réponse dépend du sûr que les autres classes (Duration, DateTime) sont. Je suppose que ce sont des classes JodaTime, et un rapide coup d'œil sur javadoc indique que ces classes produisent des instances thread-safe et immuables, donc pour cette raison, la sortie devrait toujours être la même. En fait, étant donné que toutes les parties constituantes de ce calcul sont immuables (toutes les instances de DateTime et Duration), vous devriez être en mesure de vous en passer sans aucune synchronisation ni aucun élément compareAndSet atomique du tout.
Oui, mais les primitives atomiques sont plus efficaces.