Bạn có thể sử dụng thể hiện Gson làm trường tĩnh trong bean mô hình (tái sử dụng) không?


138

Đây là mô hình tôi đã triển khai:

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);
    }
}

Tôi nghĩ rằng thật vô ích khi tạo phiên bản Gson mới cho mọi phiên bản Đăng nhập.

Nhưng điều tôi lo lắng là vấn đề an toàn luồng. Khoảng hơn 1000 trường hợp / giây sẽ được tạo.

Có thể sử dụng thể hiện Gson làm trường tĩnh không?

Cảm ơn cho bất kỳ lời khuyên / sửa chữa.

Câu trả lời:


133

Nó có vẻ tốt với tôi. Không có gì trong trường hợp GSON làm cho nó liên quan đến một thể hiện cụ thể LoginSession, vì vậy nó phải là tĩnh.

Các phiên bản GSON phải an toàn cho luồng và có một lỗi liên quan đến lỗi đã được sửa.


@slott, làm thế nào để các bạn pool / tái sử dụng các trường hợp Gson? Bạn có khởi tạo một lần mỗi khi bạn cần nối tiếp không? Hoặc sử dụng một poollocal?
Dilum Ranatunga

Chúng tôi sử dụng GSON cùng với Google Volley và khi chúng tôi phân tích dữ liệu JSON đồng thời, chúng tôi thấy vấn đề này. Từ những gì tôi có thể thấy điều này có liên quan đến thực tế là chúng ta xác định dấu thời gian để phân tích giá trị datetime.
slott

1
Thời gian không phải là luồng an toàn, đó có thể là nguyên nhân, không phải là GSON không phải là luồng an toàn.
Andreas Mattisson

20

Các Gsonlớp cốt lõi là an toàn chủ đề. Tôi vừa gặp phải một vấn đề an toàn luồng được cho là với GSON. Vấn đề xảy ra khi sử dụng một tùy chỉnh JsonDeserializerJsonSerializerđể Datephân tích cú pháp và định dạng. Khi nó bật ra, vấn đề an toàn luồng là với việc sử dụng một thể hiện tĩnh SimpleDateFormatkhông an toàn cho luồng của phương thức của tôi . Khi tôi bọc tĩnh SimpleDateFormattrong một ThreadLocalví dụ, mọi thứ đều ổn.


4
Một tùy chọn tốt hơn có thể là sử dụng Apache commons FastDateFormat (một phần của commons-lang), đây là chủ đề an toàn rõ ràng. commons.apache.org/proper/commons-lang/apidocs/org/apache/ cho
Marceau

Cảm ơn @Zaan. Mẹo tuyệt vời!
entpnerd

8

Theo các ý kiến, bài kiểm tra đơn vị hiện tại không thực sự kiểm tra nhiều, hãy cẩn thận với bất kỳ điều gì liên quan đến an toàn luồng ...

Có một bài kiểm tra đơn vị kiểm tra độ an toàn của luồng:

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

Bạn có thể tự hỏi nếu kiểm tra đơn vị này là đủ để tìm thấy mọi vấn đề có thể có trên mọi cấu hình máy có thể? Bất kỳ ý kiến ​​về điều này?

Ngoài ra còn có câu này trong các tài liệu :

Ví dụ Gson không duy trì bất kỳ trạng thái nào trong khi gọi các hoạt động của Json. Vì vậy, bạn có thể tự do sử dụng lại cùng một đối tượng cho nhiều hoạt động tuần tự hóa và giải tuần tự Json.


3
Tôi đã có thể nói rằng bài kiểm tra đơn vị này là không đủ để phát hiện các vấn đề tương tranh. Đầu tiên, MyObject là một lớp tầm thường không có các bộ sưu tập phức tạp liên quan nên việc hủy / xê-ri hóa đồng thời các danh sách và bản đồ và các đối tượng phức tạp khác không được kiểm tra. Thứ hai, việc xê-ri hóa chỉ được lặp lại 10 lần cho mỗi trong số 10 luồng, không đầy đủ. Thứ ba, dù sao thì các lỗi đồng thời rất khó kiểm tra vì các cấu hình phần cứng khác nhau có các đặc điểm thời gian chạy khác nhau, do đó, mọi thử nghiệm sẽ chỉ có hiệu lực nếu được đảm bảo chạy trên tất cả các cấu hình.
Lawrence Dol

1
Ví dụ, thử nghiệm này có thể sẽ không tìm thấy bất kỳ lỗi đồng thời nào trên một máy lõi đơn, vì mỗi luồng có thể sẽ hoàn thành trong một khoảng thời gian duy nhất và do đó các luồng sẽ chạy liên tục, không đồng thời.
Lawrence Dol

3
Không phải nói nó không an toàn, chỉ có điều là bài kiểm tra này thậm chí không đảm bảo từ xa.
Lawrence Dol

1

Chúng tôi đã gặp sự cố với an toàn luồng một thời gian trước và chúng tôi đã giải quyết nó bằng cách sử dụng FastDateFormat trong apache commons.

Chỉ cần tạo một liên kết chính cho Gist xung quanh điều này để giúp mọi người tự hỏi liệu các trường hợp Gson có thể được sử dụng lại không. Họ không có setters và tất cả các vars là riêng tư.

Vì vậy, ngoài vấn đề SimpleDateFormat, tôi không thấy họ duy trì trạng thái ở bất kỳ nơi nào khác.

Hãy kiểm tra xem ra. Đây là lần đầu tiên tôi trả lời một trong những điều này. Hạnh phúc khi nhận lại một lần. :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.