Чи добре використовувати екземпляр Gson як статичне поле в модельному бобі (повторне використання)?


138

Ось модель, яку я реалізував:

public class LoginSession {
    private static final Gson gson = new Gson();

    private String id;
    private String name;
    private long timestamp;

    public LoginSession(String id, String name) {
        this.id = id;
        this.name = name;
        this.timestamp = System.currentTimeMillis();
    }

    public String toJson() {
        return gson.toJson(this);
    }

    public static LoginSession fromJson(String json) {
        checkArgument(!isNullOrEmpty(json));
        return gson.fromJson(json, LoginSession.class);
    }
}

Я думав, що марно створювати новий екземпляр Gson для кожного екземпляра LoginSession.

Але те, що мене хвилює, - це питання безпеки безпеки. Буде створено приблизно 1000+ екземплярів / сек.

Чи добре використовувати екземпляр Gson як статичне поле?

Дякуємо за будь-які поради / виправлення.

Відповіді:


133

Мені це здається прекрасним. Ніщо в екземплярі GSON не робить це пов'язаним з конкретним екземпляром LoginSession, тому воно повинно бути статичним.

Екземпляри GSON повинні бути безпечними для потоків , і виникла помилка щодо виправленого.


@slott, як ви збираєте / використовуєте екземпляри Gson? Чи інстанціюєте ви кожен раз, коли вам потрібно буде серіалізувати? Або використовувати нитковий пул?
Dilum Ranatunga

Ми використовуємо GSON разом з Google Volley, і коли ми одночасно аналізуємо дані JSON, ми бачимо цю проблему. З того, що я бачу, це пов'язано з тим, що ми визначаємо часову позначку для розбору значень дати.
слот

1
Datetime не є безпечним для потоків, це може бути причиною, а не те, що GSON не є безпечним для потоків.
Андреас Маттіссон

20

Основний Gsonклас є безпечним для потоків. Я щойно стикався з проблемою безпеки потоку, яка нібито була з GSON. Проблема сталася під час використання користувацького режиму JsonDeserializerта JsonSerializerдля Dateрозбору та форматування. Як виявилося, проблема безпеки потоку полягала у використанні мого методу статичного SimpleDateFormatекземпляра, який не є безпечним для потоків. Після того, як я загорнув статику SimpleDateFormatв ThreadLocalекземпляр, все вийшло нормально.


4
Кращим варіантом може бути використання Apache commons FastDateFormat (частина commons-lang), що явно є безпечним для потоків. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Марсо

Дякую @Zaan. Чудова порада!
entpnerd

8

Відповідно до коментарів, існуючий блок тесту насправді не дуже перевіряє, будьте обережні з будь-чим, що стосується безпеки ниток ...

Існує тестова перевірка на безпеку різьби:

/**
 * Tests for ensuring Gson thread-safety.
 *
 * @author Inderjeet Singh
 * @author Joel Leitch
 */
public class ConcurrencyTest extends TestCase {
  private Gson gson;
  ...

Вам може бути цікаво, чи достатньо цього тесту на пристрій, щоб знайти всі можливі проблеми у кожній можливій конфігурації машини? Будь-які коментарі з цього приводу?

Існує також цю пропозицію в документації :

Примірник Gson не підтримує жодного стану під час виклику операцій Json. Отже, ви можете повторно використовувати один і той же об'єкт для декількох операцій серіалізації та десеріалізації Json.


3
Я б сказав, що ця тестова одиниця була надзвичайно неадекватною для виявлення проблем одночасності. По-перше, MyObject - це тривіальний клас, в якому не задіяні складні колекції, тому паралельна де / серіалізація списків і карт та інших складних об'єктів не перевіряється. По-друге, серіалізація повторюється лише 10 разів на кожну з 10 ниток, що є недостатньою. По-третє, помилки одночасності важко перевірити в будь-якому випадку, оскільки різні конфігурації апаратних засобів мають різні характеристики часу виконання, тому будь-який тест був би дійсним лише за умови гарантії виконання всіх конфігурацій.
Лоуренс Дол

1
Наприклад, цей тест, ймовірно, не знайде жодної помилки одночасності на одній основній машині, оскільки кожен потік, ймовірно, завершиться протягом одного часового відрізка, і тому потоки будуть виконуватися послідовно, а не одночасно.
Лоуренс Дол

3
Не треба сказати, що це не безпечно для ниток, лише те, що цей тест навіть не гарантує віддаленості.
Лоуренс Дол

1

У нас були проблеми з безпекою потоку, і ми вирішили це за допомогою FastDateFormat в апаш-вілі.

Щойно створили посилання для Gist навколо цього, щоб допомогти людям цікавитись, чи можна використовувати екземпляри Gson. Вони не мають сетерів, і всі вар є приватними.

Тож крім проблеми SimpleDateFormat я більше не бачу, щоб вони підтримували стан ніде.

Зроби це перевірити . Це я вперше відповідаю на одне із них. Раді віддати за один раз. :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.