Menu
CoddyTech

Singleton yang Aman untuk Thread

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C# di Coddy. Pelajaran 52 dari 70.

Pola Singleton memastikan sebuah class hanya memiliki satu instance di seluruh aplikasimu dan menyediakan titik akses global untuknya. Pola ini berguna untuk mengelola sumber daya bersama, seperti pengaturan konfigurasi, layanan pencatatan log, atau koneksi database.

Singleton dasar menggunakan constructor privat untuk mencegah pembuatan instance dari luar dan property statis untuk menyediakan akses:

public class Logger
{
    private static Logger _instance;
    private static readonly object _lock = new object();
    
    private Logger() { }  // Konstruktor privat
    
    public static Logger Instance
    {
        get
        {
            lock (_lock)
            {
                if (_instance == null)
                    _instance = new Logger();
                return _instance;
            }
        }
    }
    
    public void Log(string message) => Console.WriteLine(message);
}

Pernyataan lock memastikan keamanan thread. Jika beberapa thread mencoba mengakses Instance secara bersamaan, hanya satu thread yang dapat memasuki bagian kritis dalam satu waktu. Tanpa ini, dua thread dapat sama-sama melihat _instance bernilai null dan membuat instance terpisah.

C# menawarkan pendekatan aman untuk thread yang lebih sederhana menggunakan inisialisasi statis:

public class Logger
{
    private static readonly Logger _instance = new Logger();
    
    private Logger() { }
    
    public static Logger Instance => _instance;
    
    public void Log(string message) => Console.WriteLine(message);
}

Versi ini aman untuk thread karena CLR menjamin inisialisasi field statis hanya terjadi satu kali. Kedua pendekatan memastikan kamu selalu mendapatkan instance yang sama:

Logger.Instance.Log("First call");
Logger.Instance.Log("Same instance");
challenge icon

Tantangan

Mudah

Mari buat pengelola konfigurasi yang aman untuk thread menggunakan pola Singleton. Dalam aplikasi nyata, pengaturan konfigurasi perlu dapat diakses di seluruh program, sekaligus memastikan hanya ada satu instance, sehingga Singleton sangat cocok digunakan.

Kamu akan mengatur kodemu dalam dua file:

  • ConfigManager.cs: Buat class ConfigManager di namespace Configuration yang menerapkan pola Singleton. Pengelola konfigurasimu harus:
    • Memiliki field static private untuk menyimpan satu-satunya instance
    • Menggunakan constructor private untuk mencegah pembuatan instance dari luar
    • Menyediakan property static Instance yang mengembalikan satu-satunya instance (gunakan pendekatan inisialisasi static yang lebih sederhana agar aman untuk thread)
    • Menyertakan field string private _appName yang diinisialisasi dengan "MyApp"
    • Memiliki method SetAppName(string name) untuk memperbarui nama aplikasi
    • Memiliki method GetAppName() yang mengembalikan nama aplikasi saat ini
  • Program.cs: Dalam file utamamu, tunjukkan bahwa Singleton berfungsi dengan benar dengan mengakses instance beberapa kali dan memperlihatkan bahwa perubahan tetap berlaku di semua referensi.

Kamu akan menerima satu input:

  • Nama aplikasi baru yang akan ditetapkan (misalnya, ProductionServer)

Dalam programmu:

  1. Dapatkan instance ConfigManager dan cetak nama aplikasi default
  2. Dapatkan instance itu lagi (ke variabel yang berbeda) dan gunakan untuk menetapkan nama aplikasi baru dari input
  3. Dapatkan instance itu untuk ketiga kalinya dan cetak nama aplikasi untuk membuktikan bahwa semua referensi menggunakan data yang sama

Misalnya, jika inputnya adalah ProductionServer, outputnya akan berupa:

MyApp
ProductionServer

Ini menunjukkan manfaat utama Singleton, yaitu berapa kali pun kamu mengakses Instance, kamu akan selalu mendapatkan object yang sama dengan state bersama. Pendekatan inisialisasi static menjamin keamanan thread karena CLR memastikan field static diinisialisasi hanya sekali, bahkan jika beberapa thread mengaksesnya secara bersamaan.

Coba sendiri

using System;
using Configuration;

class Program
{
    public static void Main(string[] args)
    {
        // Baca input, yaitu nama aplikasi baru
        string newAppName = Console.ReadLine();
        
        // TODO: Ambil instance ConfigManager dan tampilkan nama aplikasi bawaan
        
        // TODO: Ambil lagi instance tersebut (ke variabel lain) dan gunakan untuk mengatur nama aplikasi baru
        
        // TODO: Ambil instance untuk ketiga kalinya dan tampilkan nama aplikasi untuk membuktikan bahwa semua referensi berbagi data yang sama
    }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler C# online