모델 빈에서 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);
    }
}

모든 LoginSession 인스턴스마다 새 Gson 인스턴스를 만드는 것이 쓸모 없다고 생각했습니다.

그러나 내가 걱정하는 것은 스레드 안전성 문제입니다. 약 1000 개 이상의 인스턴스 / 초가 생성됩니다.

정적 필드로 Gson 인스턴스를 사용해도 괜찮습니까?

조언 / 수정에 감사드립니다.

답변:


133

나에게 괜찮아 보인다. GSON 인스턴스에는의 특정 인스턴스와 관련된 것은 LoginSession없으므로 정적이어야합니다.

GSON 인스턴스는 스레드 안전해야 하고, 거기 에 대한 버그 수정 된 것으로는.


@ 슬롯, 어떻게 Gson 인스턴스를 풀 / 재사용합니까? 직렬화해야 할 때마다 하나를 인스턴스화합니까? 아니면 threadlocal 풀을 사용 하시겠습니까?
Dilum Ranatunga

GSON을 Google Volley와 함께 사용하며 JSON 데이터를 동시에 구문 분석 할 때이 문제가 발생합니다. 내가 볼 수 있듯이 이것은 날짜 시간 값을 구문 분석하기위한 타임 스탬프를 정의한다는 사실과 관련이 있습니다.
Slott

1
날짜 시간은 스레드 안전이 아니므로 GSON이 스레드 안전이 아닌 원인이 될 수 있습니다.
Andreas Mattisson

20

핵심 Gson클래스는 스레드로부터 안전합니다. 방금 GSON과 관련하여 스레드 안전성 문제가 발생했습니다. 사용자 정의를 사용하는 경우이 문제는 발생 JsonDeserializerJsonSerializer위해 Date분석 및 서식. 결과적으로 스레드 안전 문제는 SimpleDateFormat스레드 안전하지 않은 정적 인스턴스를 사용하는 메소드와 관련이 있습니다. 인스턴스 에서 정적 SimpleDateFormat을 래핑하면 ThreadLocal모든 것이 잘 작동했습니다.


4
더 나은 옵션은 명시 적으로 스레드 안전성 인 Apache commons FastDateFormat (commons-lang의 일부)을 사용하는 것입니다. commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau

감사합니다 @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 회만 반복되며 이는 부적절합니다. 셋째, 서로 다른 하드웨어 구성이 서로 다른 런타임 특성을 갖기 때문에 동시성 결함을 테스트하기가 어려워서 모든 구성에서 실행되도록 보장 된 경우에만 모든 테스트가 유효합니다.
Lawrence Dol

1
예를 들어,이 테스트는 단일 코어 머신에서 동시성 결함을 찾지 못할 것입니다. 각 스레드는 단일 타임 슬라이스 내에서 완료되어 스레드가 동시에 연속적으로 실행되지 않기 때문입니다.
Lawrence Dol

3
스레드 안전하지 않다는 것은 말할 것도없고,이 테스트 만이 원격 테스트를 보장하지는 않습니다.
Lawrence Dol

1

우리는 잠시 스레드 안전성에 문제가 있었고 Apache 공통점에서 FastDateFormat을 사용하여 문제를 해결했습니다.

Gson 인스턴스를 재사용 할 수 있는지 궁금해하는 사람들을 돕기 위해 요점에 대한 요점 링크를 만들었습니다 . 그들은 세터가 없으며 모든 vars는 비공개입니다.

따라서 SimpleDateFormat 문제 이외의 다른 곳에서는 상태를 유지하는 것으로 보이지 않습니다.

확인 하십시오 . 이것들 중 하나에 답장하는 것은 처음입니다. 한 번 돌려주는 것이 행복합니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.