Csharp/CSharp Tutorial/Thread/lock

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Lock Demo

The lock keyword is used when working with multiple threads.

Its general form is shown here:


<source lang="csharp">lock(obj) {

   // critical section 
   }</source>

Multi Threaded Printing (Synchronizing Threads)

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; public class Printer {

   public void PrintNumbers() {
       lock (this) {
           Console.WriteLine("-> {0} is executing PrintNumbers()", Thread.CurrentThread.Name);
           Console.Write("Your numbers: ");
           for (int i = 0; i < 10; i++) {
               Random r = new Random();
               Thread.Sleep(1000 * r.Next(5));
               Console.Write(i + ", ");
           }
           Console.WriteLine();
       }
   }

} class Program {

   static void Main(string[] args) {
       Printer p = new Printer();
       Thread[] threads = new Thread[10];
       for (int i = 0; i < 10; i++) {
           threads[i] = new Thread(new ThreadStart(p.PrintNumbers));
           threads[i].Name = string.Format("Worker thread #{0}", i);
       }
       foreach (Thread t in threads)
           t.Start();
       Console.ReadLine();
   }

}</source>

Shared resource without lock

<source lang="csharp">using System; using System.Threading; class MainClass {

 private int Runs = 0;
 public  void CountUp() 
 {
   while (Runs < 10)
   {
     int Temp = Runs;
     Temp++;
     Console.WriteLine(Thread.CurrentThread.Name + " " + Temp);
     Thread.Sleep(1000);
     Runs = Temp;
   }
 }
 public void RunThreads()
 {
   Thread t2 = new Thread(new ThreadStart(CountUp));
   t2.Name = "t2";
   Thread t3 = new Thread(new ThreadStart(CountUp));
   t3.Name = "t3";
   t2.Start();
   t3.Start();
 }
 public static void Main() 
 {
   MainClass ex = new MainClass();
   ex.RunThreads();
 }

}</source>

t2 1
t3 1
t2 2
t3 2
t2 3
t3 3
t2 4
t3 4
t2 5
t3 5
t2 6
t3 6
t3 7
t2 7
^CTerminate batch job (Y/N)? n

Use lock to synchronize access to an object

<source lang="csharp">using System; using System.Threading;

class MyThread {

 public Thread thrd;  

 public MyThread(string name, int[] nums) {  
   thrd = new Thread(this.run); 
   thrd.Name = name; 
   thrd.Start();
 }  
 
 void run() {  
   int answer = sumIt(10);           
 }  
 public int sumIt(int nums) {  
   lock(this) { 
      Console.WriteLine(Thread.CurrentThread.Name);  
      Thread.Sleep(100);
     }  
     return 0; 
 } 

}


class MainClass {

 public static void Main() {  
   int[] a = {1, 2, 3, 4, 5};  
 
   MyThread mt1 = new MyThread("Child #1", a);  
   MyThread mt2 = new MyThread("Child #2", a);  
 
   mt1.thrd.Join();  
   mt2.thrd.Join();  
 }  

}</source>

Child #1
Child #2

Use of volatile: lock singleton

<source lang="csharp">using System; class Singleton {

   static object sync = new object();
   
   static volatile Singleton singleton = null;
   
   private Singleton()
   {
   }
   
   public static Singleton GetSingleton()    
   {
       if (singleton == null)
       {
           lock(sync)
           {
               if (singleton == null)
               singleton = new Singleton();
           }
       }
       
       return(singleton);
   }

}</source>

Use the lock object

<source lang="csharp">using System; using System.Threading; class MainClass {

 private int Runs = 0;
 public  void CountUp() 
 {
   while (Runs < 10)
   {
     lock(this)
     {
       int Temp = Runs;
       Temp++;
       Console.WriteLine(Thread.CurrentThread.Name + " " + Temp);
       Thread.Sleep(1000);
       Runs = Temp;
     }
   } 
 }
 public void RunThreads()
 {
   Thread t2 = new Thread(new ThreadStart(CountUp));
   t2.Name = "t2";
   Thread t3 = new Thread(new ThreadStart(CountUp));
   t3.Name = "t3";
   t2.Start();
   t3.Start();
 }
 public static void Main() 
 {
   MainClass ex = new MainClass();
   ex.RunThreads();
 }

}</source>

t2 1
t3 2
t2 3
t3 4
t2 5
t3 6
t2 7
t3 8
t2 9
t3 10
t2 11

Using Lock

<source lang="csharp">using System; using System.Threading; class MainClass {

 static void Main(string[] args)
 {
   CounterWithLock me = new CounterWithLock();
   Thread[] MyThreads = new Thread[10];
   for (int i = 0; i > 100; i++)
   {
     MyThreads[i] = new Thread(new ThreadStart(me.Count));
     MyThreads[i].Start();
   }
 }

} class CounterWithLock {

 private int counter;
 
 public void Count()
 {
   lock (this)
   {
     counter++;
   }
 }

}</source>