Как сделать статический поток в Календаре безопасным - PullRequest
8 голосов
/ 05 июня 2011

Я хотел бы использовать Календарь для некоторых статических методов и использовать статическое поле:

private static Calendar calendar = Calendar.getInstance();

Теперь я читаю java.util.Calendar не является поточно-ориентированным. Как я могу сделать этот поток безопасным (это должно быть static )?

Ответы [ 4 ]

14 голосов
/ 05 июня 2011

Вы не можете сделать что-то поточно-ориентированное, если это не так. В случае Calendar даже чтение данных из них не является поточно-ориентированным, поскольку может обновлять внутренние структуры данных.

Если это вообще возможно, я бы рекомендовал использовать Joda Time вместо:

  • Большинство типов являются неизменяемыми
  • Неизменяемые типы являются поточно-ориентированными
  • Как правило, API намного лучше

Если у вас абсолютно есть для использования Calendar, вы можете создать блокирующий объект и поставить весь доступ через блокировку. Например:

private static final Calendar calendar = Calendar.getInstance();
private static final Object calendarLock = new Object();

public static int getYear()
{
    synchronized(calendarLock)
    {
        return calendar.get(Calendar.YEAR);
    }
}

// Ditto for other methods

Хотя это довольно противно. Конечно, вы можете иметь только один синхронизированный метод, который создавал клон исходного календаря каждый раз, когда это было необходимо, конечно ... возможно, что, вызвав computeFields или computeTime, вы могли бы сделать последующие операции чтения, конечно, поточно-ориентированные, но лично я не хотел бы попробовать это.

4 голосов
/ 05 июня 2011

Календарь является потокобезопасным, если вы его не измените. Использование в вашем примере хорошо.

Стоит отметить, что Calendar не является эффективным классом, и его следует использовать только для сложных операций (например, для поиска следующего месяца / года). ИМХО: Если вы используете его для сложных операций, используйте только локальные переменные.

Если вам нужен только моментальный снимок, более быстрый способ - использовать currentTimeMillis, который даже создает объект. Вы можете сделать поле нестабильным, если хотите сделать его безопасным для потоков.

private static long now = System.currentTimeMillis();

Использование немного подозрительно. Зачем вам получать текущее время и хранить его во всем мире, как это. Это напоминает мне о старой шутке.

- У вас есть время?
- Да, у меня это где-то записано.

2 голосов
/ 05 июня 2011

Вы не можете.Да, вы можете синхронизировать его, но он все еще имеет изменяемые поля состояния.Вам нужно будет создать свой собственный объект Calendar.

Если возможно, использовать что-то более легкое, например, длительное измерение времени в миллисекундах, и преобразовывать его в Calendar только тогда, когда вам НУЖНО.

0 голосов
/ 05 июня 2011

Создайте Calendar как локальную переменную в методе. Если вам нужен один и тот же календарь для разных методов, вы можете использовать статику, где более подходящим является объект (синглтон или квази-синглтон).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...