Singleton là một Design pattern rất hay được sử dụng trong thực tế. Tuy nhiên cách triển khai nó trong Java một cách hiệu quả thì không phải ai cũng nắm được.
Sau đây chúng tôi sẽ giới thiệu về Singleton và cách triển khai nó trong Java.
Ưu điểm
  • Chỉ tồn tại duy nhất 1 Instance của class Singleton được tạo ra trong suốt chương trình
  • Dễ dàng triển khai
  • Cung cấp việc truy cập vào Object global
Triển khai
  • Tư tưởng để triển khai việc này chính là để private constructor để kiểm soát việc tạo Instance của class Singleton.
  • Sử dụng
Muốn gọi hàm doMethodA() của class Singleton như sau: Singleton.GetInstance().doMethodA()
Một số vấn đề
          Singleton trong multi-thread.
1. Eager load
Do biến member instance đang để static nên ta hoàn toàn không cần sử dụng synchrozied ở đây. Biến static member được khởi tạo 1 lần duy nhất ngay khi loadClass Singleton.
Tuy nhiên việc khởi tạo biến instance ngay từ lúc load class, có thể sẽ khiến việc load class bị chậm. Đặc biệt là vs trường hợp khởi tạo class Singleton phức tạp, tốn nhiều ram.
Để giải quyết việc đó, thì mọi người hay sử dụng lazy-load để khởi tạo biến instance. Biến instance sẽ chỉ được khởi tạo khi nó thực sự được sử dụng.
2. Lazy-load synchronized method
Với việc sử dụng synchronized ở method thì tất cả các thread đều bị synchronized, trong khi thực tế chỉ chỉ cần 1 vài thread đầu tiên cần.
Để tránh việc đó ta có thể sử dụng phương pháp Double check synchronized như sau:
3. Lazy load Double check synchronized
  1. public class Singleton { private volatile Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized(Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } public void doMethodA() { } }
Lưu ý: Khi sử dụng phương pháp này, cần phải để biến instance là volatile. volatile sẽ đảm bảo rằng biến instance được read value sau khi write value. Nó sẽ đảm bảo việc xử lý của các thread được chính xác.
4. Initialization on demand holder phương pháp này được viết bởi Bill Pugh của trường đại học University of Maryland.
Phương pháp này không cần phải synchrozied mà vẫn đảm bảo thread safe, giúp tăng performance.
Theo như bài viết tại
http://literatejava.com/jvm/fastest-threadsafe-singleton-jvm/
Tác giả đã đo performance giữa các phương pháp trên.
Kết quả cho thấy phương pháp Initialization on demand holder chạy nhanh nhất.
5. Enum
 
public enum Singleton { INSTANCE; public void doMethodA() { } }
Trong cuốn sách Effective Java, Joshua Bloch đã khẳng định rằng “sử dụng enum type là cách tốt nhất để triển khai Singleton” cho bất kì ngôn ngữ nào mà hỗ trợ enums.
Việc sử dụng Enum rất dễ để triển khai, lazy loadthread safe, hỗ trợ serializetrong Java.
Ứng dụng
  • Vì class Singleton chỉ tồn tại 1 Instance nên nó hay được dùng cho các trường hợp giải quyết các bài toán cần truy cập vào các shared resource hoặc implement cho các Logger classConfiguration class hoặc DAO.
  • Một số design pattern khác cũng sử dụng Singleton để triển khai: Factory, Abstract Factory …
Link tham khảo:
https://en.wikipedia.org/wiki/Singleton_pattern
Dương Thanh Hải – FTI
Tin liên quan: