Singleton design pattern

Table of contents

Đĩnh nghĩa
Singleton là một design pattern đảm bảo chỉ có duy nhất 1 instance dc tạo ra, và instance ở dạng global.
Hãy thử tưởng tượng bạn đang lập trình backend kết nối đến một cợ sở dữ liệu, bạn muốn chỉ có duy nhất một kết nối đến db được khởi tạo để tránh lãng phí tài nguyên, thì Singleton chính là cứu cánh.
Implementation
Làm sao để implement singleton. Để implement singleton thì có 3 nhân tố chính:
Private constructor: đảm bảo rằng instance chỉ được khởi tạo bên trong class
Static variable: giữ một instance duy nhất trong class, khi class được gọi thì instance này luôn được trả về
GetInstance() method: cung cấp phương thức để class bên ngoài có thể lấy được instance của class
Singleton cơ bản
Nhưng
Đời thì không như là mơ. Nếu ứng dụng của ta là multi thread, thì 2 thread độc lập có thể cùng lúc tạo đến 2 instance khác nhau. Dù vậy, có một số cách để giải quyết vấn đề và multi threading.
Cách 1: Dùng lock
Sử dụng lock cho phần khởi tạo, đảm bảo duy nhất 1 thread được phép lấy instance, các instance khác phải chờ đợi cho đến khi không còn thread nào truy cập đến nữa.
Nhược điểm: của cách này là lock method tốn chi phí. vì chỉ có lúc đầu khi instance chưa được tạo thì mới cần đến lock.
Dùng locking đảm bảo duy nhất một thread gọi Instance
Cách 2: Eager created
Nếu việc tạo instance gây ra tốn tài nguyên ko đáng kể (vì instance được tạo có thể ko được sử dụng) thì có thể sử dụng eager created.(tạo instance ngay khi khởi chạy).
Nhược điểm: cách này thì cần phải đảm bảo các instance được sử dụng, không thì sẽ tốn tài nguyên. Tuy nhiên mình thấy ảnh hưởng cũng tương đối nhỏ.
Khởi tạo trước instance
Cách 3: Double-check locking
Cách này giải quyết được vấn đề với 2 cách trên đó là chỉ tạo instance khi được gọi đến và chỉ lock duy nhất với lần đầu.
Ý tưởng đơn giản là ta kiểm tra instance được tạo hay chưa, nếu chưa được tạo thì mới lock để tạo instance, tránh việc luôn lock khi được gọi đến.
Double-check locking, chỉ tạo lock khi cần khởi tạo
LƯU Ý
Mặc dù vậy Singleton có thể không hoạt đông như mong muốn nếu dùng với reflection, serialization. Ở ví dụ dưới đây kết quả sẽ trả về là “Not OK” do dùng reflection để khởi tạo instance.
2 instance hoàn toàn khác nhau do được tạo bằng reflection
Subscribe to my newsletter
Read articles from Huy Nguyen directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Huy Nguyen
Huy Nguyen
I am a software engineer with 4 years of experience in developing web applications. My expertise lies in backend development, and I have a deep interest in problem-solving, algorithms, system design, and databases. I am always eager to learn and embrace challenging projects, striving to deliver applications that exceed user expectations. I also love sharing my knowledge and learning from others to foster mutual growth and improvement