ตกลงเพื่อใช้อินสแตนซ์ Gson เป็นเขตข้อมูลคงที่ใน model bean (นำมาใช้ใหม่) หรือไม่


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

แต่สิ่งที่ฉันกังวลคือปัญหาความปลอดภัยของเธรด ประมาณ 1,000+ ครั้ง / วินาทีจะถูกสร้างขึ้น

ตกลงเพื่อใช้อินสแตนซ์ Gson เป็นเขตข้อมูลแบบคงที่หรือไม่

ขอบคุณสำหรับคำแนะนำ / การแก้ไขใด ๆ

คำตอบ:


133

ดูเหมือนดีสำหรับฉัน ไม่มีสิ่งใดในอินสแตนซ์ GSON ที่ทำให้มันเกี่ยวข้องกับอินสแตนซ์เฉพาะของLoginSessionดังนั้นมันควรจะคงที่

อินสแตนซ์ GSON ควรปลอดภัยต่อเธรดและมีข้อผิดพลาดเกี่ยวกับสิ่งที่ได้รับการแก้ไข


@slott คุณจะรวมกลุ่ม / ใช้ Gson อินสแตนซ์ใหม่ได้อย่างไร คุณยกตัวอย่างหนึ่งครั้งทุกครั้งที่คุณต้องการทำให้เป็นอันดับหรือไม่ หรือใช้เธรดพูลเธรด
Dilum Ranatunga

เราใช้ GSON ร่วมกับ Google Volley และเมื่อเราแยกวิเคราะห์ข้อมูล JSON พร้อมกันเราจะเห็นปัญหานี้ จากสิ่งที่ฉันเห็นนี้เกี่ยวข้องกับความจริงที่ว่าเรากำหนดเวลาประทับสำหรับการแยกค่าวันที่และเวลา
slott

1
Datetime ไม่ใช่เธรดที่ปลอดภัยซึ่งอาจเป็นสาเหตุไม่ใช่ GSON ที่ไม่ปลอดภัยสำหรับเธรด
Andreas Mattisson

20

Gsonระดับแกนกลางมีความปลอดภัยต่อเธรด ฉันเพิ่งพบปัญหาความปลอดภัยของเธรดที่ควรใช้กับ GSON ปัญหาที่เกิดขึ้นเมื่อมีการใช้ที่กำหนดเองJsonDeserializerและJsonSerializerสำหรับDateการแยกและการจัดรูปแบบ ตามที่ปรากฏปัญหาความปลอดภัยของเธรดเกิดจากการใช้SimpleDateFormatอินสแตนซ์แบบคงที่ซึ่งไม่ได้เป็นวิธีที่ปลอดภัยสำหรับเธรดของฉัน เมื่อฉันห่อคงSimpleDateFormatในThreadLocalตัวอย่างทุกอย่างทำงานได้ดี


4
ตัวเลือกที่ดีกว่าอาจใช้ Apache Commons FastDateFormat (ส่วนหนึ่งของ commons-lang) ซึ่งเป็น threadsafe อย่างชัดเจน commons.apache.org/proper/commons-lang/apidocs/org/apache/…
Marceau

ขอบคุณ @Zan สุดยอดเคล็ดลับ!
เริ่ม

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
ไม่ต้องบอกว่าไม่ใช่ threadsafe เฉพาะที่การทดสอบนี้ไม่ได้รับประกันจากระยะไกลว่าเป็น
Lawrence Dol

1

เรามีปัญหากับความปลอดภัยของเธรดและเราแก้ไขได้โดยใช้ FastDateFormat ใน apache ทั่วไป

เพิ่งสร้างลิงค์สำหรับสรุปสาระสำคัญรอบ ๆ สิ่งนี้เพื่อช่วยให้ผู้คนสงสัยว่าจะสามารถนำอินสแตนซ์ของ Gson กลับมาใช้ใหม่ได้หรือไม่ พวกเขาไม่ได้มี setters และ vars ทั้งหมดเป็นส่วนตัว

ดังนั้นนอกเหนือจากปัญหา SimpleDateFormat ฉันไม่เห็นพวกเขารักษาสถานะที่อื่น

ตรวจสอบมันออก นี่เป็นครั้งแรกที่ฉันตอบกลับหนึ่งในนี้ ยินดีคืนเงินให้สักครั้ง :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.