Comment faire un Calendrier statique thread-safe
J'aimerais utiliser un Calendrier pour certaines méthodes statiques et l'utilisation d'un champ statique:
private static Calendar calendar = Calendar.getInstance();
Maintenant que j'ai lu java.util.Calendrier n'est pas thread-safe. Comment puis-je faire de ce thread-safe (il doit être statique)?
Est votre calendrier statique, juste une date fixe?
peut-être que ça aiderait à faire "volatile" ?
non, je ne veux pas créer de nombreuses instances pour chaque appel à mes méthodes, ainsi que, éventuellement, pourrait prendre du temps.
Vous voulez dire que vous êtes inquiet à propos de l'impact sur les performances de nombreux appels au constructeur?
Je commence à en conclure que le Calendrier ne doit pas être considéré comme simplement "pas thread-safe." Il doit être marqué "thread hostile".
peut-être que ça aiderait à faire "volatile" ?
non, je ne veux pas créer de nombreuses instances pour chaque appel à mes méthodes, ainsi que, éventuellement, pourrait prendre du temps.
Vous voulez dire que vous êtes inquiet à propos de l'impact sur les performances de nombreux appels au constructeur?
Je commence à en conclure que le Calendrier ne doit pas être considéré comme simplement "pas thread-safe." Il doit être marqué "thread hostile".
OriginalL'auteur cody | 2011-06-05
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas faire quelque chose de "thread-safe" si elle ne l'est pas. Dans le cas de
Calendar
, même lecture les données qu'il n'est pas thread-safe, comme il peut mettre à jour des structures de données internes.Si possible, je vous suggère de l'aide Joda Time à la place:
Si vous avez absolument ont d'utiliser un
Calendar
, vous pouvez créer un objet de verrouillage et de mettre tous les accès grâce à une serrure. Par exemple:C'est assez méchant. Vous pourriez avoir tout un méthode synchronisée qui a créé un clone de l'original calendrier chaque fois que cela était nécessaire, bien sûr... il est possible qu'en appelant
computeFields
oucomputeTime
vous pourriez faire ultérieure lecture-opérations de thread-safe, bien sûr, mais personnellement, je serais réticent à essayer.Même si une lecture sur les mises à jour du Calendrier interne de l'état, pouvez-vous donner un exemple, lorsque deux threads peut essayer de définir des valeurs différentes pour que l'état?
Eh bien, cela dépend si clone lui-même est thread-safe. Étant donné le manque de sécurité des threads dans le reste de
Calendar
, je ne voudrais pas compter sur elle.Imaginez si
areFieldsSet
devient visible commetrue
à un fil à cause du calcul dans l'autre avant que le champ calculé les valeurs elles-mêmes deviennent visibles. Il serait potentiellement possible pour un thread pour lire ancien champ de valeurs et de de nouvelles, conduisant à des résultats étranges. Je n'aime pas essayer de raisonner sur les détails d'implémentation de décider si oui ou non c'est possible.Mon réveil pourrait être mis pour me réveiller à 8 heures, heure locale, chaque jour, partout où je suis. À quelle heure zone de l'usage de sa représentation? 😉
OriginalL'auteur Jon Skeet
Calendrier est thread-safe à condition de ne pas le modifier. L'utilisation dans votre exemple est très bien.
Il est intéressant de noter que le Calendrier n'est pas efficace pour la classe et que vous devez utiliser uniquement pour des opérations complexes (comme la recherche de la prochaine mois/année) à mon humble avis: Si vous ne l'utiliser pour des opérations complexes, d'utiliser des variables locales.
Si vous souhaitez un instantané de l'époque un moyen plus rapide est d'utiliser currentTimeMillis qui n'a même créer un objet. Vous pouvez rendre le champ volatile si vous voulez vous rendre thread-safe.
L'utilisation est un peu suspect. Pourquoi voudriez-vous obtenir l'heure actuelle et de le stocker à l'échelle mondiale comme ça. Cela me rappelle une vieille blague.
La lecture qu'il ne changera pas son état de manière incohérente. Si vous étiez inquiet au sujet de ce que vous auriez à dire la même chose à propos de la Chaîne.hashCode().
Je suis d'accord que le Calendrier est méchant. Avez-vous essayé la Sérialisation? Il envoie la totalité des informations de Fuseau horaire qui n'est pas idéal pour les performances, mais cela signifie que si vous avez un système qui est à jour de Fuseau horaire de l'information, mais vous lisez un vieux Calendrier, ou d'obtenir un Calendrier à partir d'un système qui n'est pas à jour, vous obtenez subtile Fuseau horaire questions que vous ne s'attendait pas à se produire à cause des bugs dans le code, vous ne sont pas en cours d'exécution. 😛
Voir mon commentaire de réponse à vous dans ma réponse.
String
est conçu pour être thread-safe, son hachage de la mise en cache est thread-safe": la valeur est automatiquement changé à partir de "cache" à "la valeur mise en cache". Comparez cela avecCalendar
, où unboolean
champ détermine si les champs sont définis, et les champs se sont séparés. Quelle est la garantie que toutes les modifications apportées à cet ensemble de données se produit de façon atomique, ou dans l'un ou souhaitable afin?Une partie de ce qui rend Calendrier de lenteur, de la création du Fuseau horaire et les paramètres Régionaux des objets. Si vous cache ces objets immuables, vous pouvez faire de la création d'un nouveau Calendrier plus rapide. Faire Calendrier thread-safe, vous devez le verrouiller en l'utilisant.
OriginalL'auteur Peter Lawrey
Vous ne pouvez pas. Oui, vous pouvez synchroniser sur elle, mais il a encore mutable état champs. Vous aurez à créer votre propre Calendrier de l'objet.
Si possible, utilisez quelque chose de léger, comme une longue mesurer le temps en millisecondes, et de convertir à un Calendrier lorsque vous en avez BESOIN.
OriginalL'auteur MJB
Créer un
Calendar
comme une variable locale à la méthode. Si vous avez besoin de la même calendrier sur les méthodes, vous pouvez utiliser la statique où un (singleton ou quasi-singleton) objet serait plus approprié.OriginalL'auteur Andrew Lazarus