کلمه کلیدی lock یک بلوک بیان (statement block) را بوسیله فراهم کردن قفل ممانعت-متقابل (mutual-exclusion) برای یک شئ داده شده، بعنوان قسمت بحرانی، علامت گذاری می کند؛ بیان اجرا می شود، و در نهایت قفل آزاد می شود. این بیان به شکل زیر است:
Object thisLock = new Object(); lock (thisLock) { // Critical code section. }
نکات:
کلید واژه lock اطمینان می دهد که یک ریسمان، هنگامیکه ریسمان دیگر در قسمت بحرانی است، به قسمت بحرانی کد وارد نمی شود. اگر ریسمان دیگر سعی کند به کد قفل شده وارد شود، باید منتظر بماند تا اینکه شئ آزاد شود.
کلمه کلیدی lock، متد Enter را در هنگام شروع بلوک و متد Exit را در پایان بلوک فراخوانی می کند.
بطور کلی، از قفلگزاری روی نوع های public، یا نمونه های خارج از کنترل کد برنامه تان اجتناب کنید. ساختارهای عمومی از جمله
- lock(this)
- lock(typeof (MyType))
- lock ("MyLock")
این راهنمایی را نقض می کنند:
مورد 1: اگر نمونه بتواند بصورت سراسری دستیابی شود، مشکل بوجود می آورد.
مورد 2: اگر MyType بصورت سراسری دسترسی پذیر باشد، مشکل بوجود می آورد.
مورد 3: به این دلیل که هر کدی در پردازش که از رشته ی مشابه استفاده کند، همان قفل را به اشتراک می گذارد، مشکل بوجود می آورد.
بهترین تمرین این است که قفل را روی شئ private یا روی شئ private static تعریف کرد، تا از داده هایی که برای همه نمونه ها مشترکند حفاظت شود.
مثال:
مثال زیر یک استفاده ساده از ریسمان ها بدون عملیات قفلگزاری در سی شارپ را نشان می دهد.
//using System.Threading; class ThreadTest { public void RunMe() { Console.WriteLine("RunMe called"); } static void Main() { ThreadTest b = new ThreadTest(); Thread t = new Thread(b.RunMe); t.Start(); } } // Output: RunMe called
مثال زیر از ریسمان ها و lock استفاده می کند. تا زمانیکه بیان lock موجود باشد، بلوک آن بیان یک قسمت بحرانی است و balance هرگز مقدار منفی نخواهد گرفت.
// using System.Threading; class Account { private Object thisLock = new Object(); int balance; Random r = new Random(); public Account(int initial) { balance = initial; } int Withdraw(int amount) { // This condition will never be true unless the lock statement // is commented out: if (balance < 0) { throw new Exception("Negative Balance"); } // Comment out the next line to see the effect of leaving out // the lock keyword: lock (thisLock) { if (balance >= amount) { Console.WriteLine("Balance before Withdrawal : " + balance); Console.WriteLine("Amount to Withdraw : -" + amount); balance = balance - amount; Console.WriteLine("Balance after Withdrawal : " + balance); return amount; } else { return 0; // transaction rejected } } } public void DoTransactions() { for (int i = 0; i < 100; i++) { Withdraw(r.Next(1, 100)); } } } class Test { static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } } }
سلام خدا قوت لاک کردن بعضی جا ها یک لیست را لاک می کنند توضیح می دهید؟