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:


lock(obj) {
    // critical section 
    }

Multi Threaded Printing (Synchronizing Threads)

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();
    }
}

Shared resource without lock

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();
  }
}
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

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();  
  }  
}
Child #1
Child #2

Use of volatile: lock singleton

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);
    }
}

Use the lock object

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();
  }
}
t2 1
t3 2
t2 3
t3 4
t2 5
t3 6
t2 7
t3 8
t2 9
t3 10
t2 11

Using Lock

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++;
    }
  }
}