Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C#’ta Lock Anahtar Sözcüğü

Merhaba,

Eğer birden fazla Thread üzerinde işlem gerçekleştiriyorsanız ve bu işlemler kümesinde belirli kod alanlarında tek Thread olarak işlev yapacaksanız Lock keywordünü kullanabilirsiniz. Anlayacağınız elinizde çoklu Thread akışındaki bir işlev kesitini tek kanala indirgeyerek aslında o işlem bitmeden başka kanallarda Process sürecini durdurmanızı garanti altına alacaktır. Haliyle kodunuzun sadece o anda çalıştırmak istediğiniz yer dışında Thread’lar beklemeye alınacaktır.

Örnek olarak aşağıdaki durumu ele alalım.

    class Program
    {
        static void X()
        {
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine(i + " - x |");
            }
        }
        static void Y()
        {
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine(i + " - y |");
            }
        }
        static void Main(string[] args)
        {
            Thread t1 = new Thread(new ThreadStart(X));
            Thread t2 = new Thread(new ThreadStart(Y));
            t1.Start();
            t2.Start();

            Console.Read();
        }
    }

Yukarıdaki kod bloğunu incelerseniz eğer X ve Y adında iki farklı metod farklı Thread’lar da başlatılmaktadır. Haliyle bu şekilde bir çalışmada aşağıdakine benzer sonuçlar elde edilmektedir.

C#'ta Lock Anahtar Sözcüğü

C#’ta Lock Anahtar Sözcüğü

Eğer ki biz, farklı Thread’lar da tetiklenmiş bu iki metod içerisindeki döngülerin birinin işlevi bitmeden diğerinin başlamamasını istiyorsak işte tamda böyle noktada Lock keywordünü devreye sokacağız.

    class Program
    {
        static object Kontrol = new object();
        static void X()
        {
            lock (Kontrol)
            {
                for (int i = 0; i < 50; i++)
                {
                    Console.WriteLine(i + " - x |");
                }
            }
        }
        static void Y()
        {
            lock (Kontrol)
            {
                for (int i = 0; i < 50; i++)
                {
                    Console.WriteLine(i + " - y |");
                }
            }
        }
        static void Main(string[] args)
        {
            Thread t1 = new Thread(new ThreadStart(X));
            Thread t2 = new Thread(new ThreadStart(Y));
            t1.Start();
            t2.Start();

            Console.Read();
        }
    }

Çalışmamızda gördüğünüz gibi lock keywordü ile döngüler tek Thread garantisine alınmıştır. Sonuç olarak aşağıdakine benzer bir çıktı alınacaktır.

C#'ta Lock Anahtar Sözcüğü

Bir döngü son bulunca diğeri başlamaktadır.

lock keywordünün kullanım senaryolarını çoğaltabiliriz. Lakin en çok tercih edilen noktalardan birisi Singleton tasarım desenini uyguladığımız sınıflardır.

Aşağıdaki kod bloğunu inceleyiniz.

    class MyClass
    {
        MyClass() { }
        static private MyClass nesne;

        static public MyClass NesneVer
        {
            get
            {
                if (nesne == null)
                {
                    nesne = new MyClass();
                    Console.WriteLine(nameof(MyClass) + " nesnesi üretilmiştir.");
                }
                Console.WriteLine("Var olan " + nameof(MyClass) + " nesnesi gönderilmiştir.");
                return nesne;
            }
        }
    }

MyClass isimli sınıfımıza Singleton Design Pattern uygulanarak ilgili sınıftan talepler tek bir örneğe ayarlanmıştır.

MyClass sınıfından nesne talebimizi aşağıdaki gibi yaparsak eğer…

    class Program
    {
        delegate void ASenkronMetodHandler();
        static void Main(string[] args)
        {
            ASenkronMetodHandler metod = () =>
            {
                MyClass Nesne = MyClass.NesneVer;
            };

            metod.BeginInvoke(new AsyncCallback((x) => { }), new object());
            metod.BeginInvoke(new AsyncCallback((x) => { }), new object());
            metod.BeginInvoke(new AsyncCallback((x) => { }), new object());
            metod.BeginInvoke(new AsyncCallback((x) => { }), new object());
            metod.BeginInvoke(new AsyncCallback((x) => { }), new object());

            Console.Read();
        }
    }

C#'ta Lock Anahtar Sözcüğü

Sonucuna benzer çıktılar elde edeceğiz.

Eee! Hani MyClass’a Singleton tasarımını uygulamıştık. Burada iki adet nesne oluşturulmuş!

Mesele burada iki adet nesnenin oluşturulması değil, Singleton paternine rağmen birden fazla nesnenin oluşturulabilme ihtimalidir. Bunun sebebi, Singleton tasarımını uyguladığımız sınıfa yapılan talepler farklı Threadlar üzerinden gerçekleştiriliyorsa eğer ‘nesne == null’ kontrolüne T zamanında birden fazla(n adet) talep ulaşabilmekte(ihtimal) ve bu eşzamanlı ulaşan taleplerin her biri ‘true’ olarak if koşullarından geçerek nesne üretim scopeuna erişebilmektedirler. Daha doğru bir ifadeyle erişebilme ihtimaline sahiptirler.

İşte bu yüzden MyClass sınıfına gelecek her talep neticesinde lock keywordü ile işlemlerimizi tek Thread’a indirgemeli ve çalışma mantığımızı garanti altına almalıyız.

    class MyClass
    {
        MyClass() { }
        static private MyClass nesne;
        static object Kontrol = new object();
        static public MyClass NesneVer
        {
            get
            {
                lock (Kontrol)
                {
                    if (nesne == null)
                    {
                        nesne = new MyClass();
                        Console.WriteLine(nameof(MyClass) + " nesnesi üretilmiştir.");
                    }
                    Console.WriteLine("Var olan " + nameof(MyClass) + " nesnesi gönderilmiştir.");
                }
                return nesne;
            }
        }
    }

Gördüğünüz gibi MyClass’da lock keywordü ile nesne kontrol ve üretim sürecinde başka Thread’ların çalışmasını durduruyoruz.

Yapılan bu güncelleme neticesinde aşağıdaki sonucu çıktı olarak elde ediyoruz.
C#'ta Lock Anahtar Sözcüğü

Her bir yapı farklı bir yapının yahut organizasyonun olası durumlarına hitap edebilecek tarzda geliştirilmektedir. İşte lock keywordü bu duruma çok net bir örnektir. Uygun zamanlarda kullanmanın performans ve bakım açısından maliyeti ne kadar azalttığı aşikardır.

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim…

Bunlar da hoşunuza gidebilir...

1 Cevap

  1. 04 Aralık 2016

    […] farklı Thread’lardaki işlemleri belirli bir sıralama gözeterek gerçekleştirmek için Lock yapısından faydalanmaktayız. Lock yapısı, farklı Thread’larda çalışan Processlerin […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*