线程同步 资源锁定(一)

来源:互联网 发布:无印良品水乳 知乎 编辑:程序博客网 时间:2024/05/22 15:09

要避免同步问题,最好不要在线程之间使用共享数据。如果仍需要共享数据。就需要使用同步技术。

lock语句 是简单的锁定。

InterLocked类 实现原子级的锁定。

Monitor类 优点是可以指定等待的时间参数,超过时间就不会一直等待下去。

SpinLock结构 SpinLock 减轻垃圾回收压力。尝试获取锁的线程将在重复检查的循环中等待,直至该锁变为可用为止。仅当您确定这样做可以改进应用程序的性能之后才能使用

WaitHandle类 抽象基类,用于等待信号的设置。

Mutex类 可用于指定程序单一执行。

Semaphore类 旗语类。用于处理有多个资源可供有限线程访问的情况。如三个USB口只能同时允许三个线程访问。

以下三类见下一篇

Event 类 是发出信号的类。与WaitHandle配对使用。

Barrier类

ReaderWriteLockSlim类


lock语句:

是简单的锁定。为多个线程提供自己的关键字。这个锁定的类一定要是引用类型,才能被锁定。

锁定实例类:

 LockStatus lk=new LockStatus();
            lock(lk)
            {
            //dosomething
            }

public  class LockStatus
        { }

锁定静态类:

 class Program
    {
        static void Main(string[] args)
        {
            lock (typeof(LockStatus))
            {
            //dosomething
            }
            // Console.WriteLine("class is ready");
        }
    } 
        public static  class LockStatus
        { }

InterLocked类:实现原子级的锁定。即简单的i++,i--。这个锁定只针对这样简单的锁定,但访问的速度较快。

Monitor类 优点是可以指定等待的时间参数,超过时间就不会一直等待下去。

class Program
    {
        static object obj = new object();
        static void Main(string[] args)
        {
            lock (obj)
            {
                System.Threading.Tasks.Task.Run(() => LockStatus(obj));
                System.Threading.Thread.Sleep(600);                
            }


            Console.ReadKey();
        }
  
        public static void LockStatus(object obj)
        { 
             bool lockTaken = false;
            System.Threading.Monitor.TryEnter(obj, 500, ref lockTaken);
            if (lockTaken)
            {
                try
                {
                    Console.WriteLine("dosomthing"); 
                }
                finally
                {
                    System.Threading.Monitor.Exit(obj);
                }
            }
            else 
            {
                Console.WriteLine("don't get the lock;");
            }
        }
  } 

SpinLock结构 SpinLock  减轻垃圾回收压力。尝试获取锁的线程将在重复检查的循环中等待,直至该锁变为可用为止。仅当您确定这样做可以改进应用程序的性能之后才能使用.下面的示例来自MSDN

 static void SpinLockSample1()        {            SpinLock sl = new SpinLock();            StringBuilder sb = new StringBuilder();            // Action taken by each parallel job.            // Append to the StringBuilder 10000 times, protecting            // access to sb with a SpinLock.            Action action = () =>            {                bool gotLock = false;                for (int i = 0; i < 10000; i++)                {                    gotLock = false;                    try                    {                        sl.Enter(ref gotLock);                        sb.Append((i % 10).ToString());                    }                    finally                    {                        // Only give up the lock if you actually acquired it                        if (gotLock) sl.Exit();                    }                }            };            // Invoke 3 concurrent instances of the action above            Parallel.Invoke(action, action, action);            // Check/Show the results            Console.WriteLine("sb.Length = {0} (should be 30000)", sb.Length);            Console.WriteLine("number of occurrences of '5' in sb: {0} (should be 3000)",                sb.ToString().Where(c => (c == '5')).Count());        }

WaitHandle类

class Program
    {
        delegate int delegateTask();
        static void Main(string[] args)
        {
            delegateTask d1 = threadRun;
            var result = d1.BeginInvoke(null, null);
            while (true)
            {
                if(result.AsyncWaitHandle.WaitOne(100,false))
                {
                    break;
                }
            }
            int a = d1.EndInvoke(result);
            Console.WriteLine("结果是{0}", a);
            Console.ReadKey();
        }
      private static int threadRun()
      {       
          Thread.Sleep(500);
          return 12;
      }

Mutex类 可用于指定程序单一执行。

 bool createNew;
            var mutex = new System.Threading.Mutex(false, "singletonWinAppMutex",out createNew);
            if (!createNew)
            {
                Console.WriteLine("已经有程序在运行");
                Console.ReadKey();
            }
            else 
            {
                Console.WriteLine("程序正在运行");
                Console.ReadKey();
            }

Semaphore类

 class Program
    {
        static void Main(string[] args)
        {
            int taskCount = 6;
            int semaphoreCount = 3;
            SemaphoreSlim semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
            Task[] tasks=new Task[taskCount];
            for (int i = 0; i < taskCount; i++)
            {
                tasks[i] = Task.Run(() => TaskMain(semaphore));
            }
            Task.WaitAll(tasks);
            Console.WriteLine("Task is Completed");
            Console.ReadKey();
        }
        private static void TaskMain(SemaphoreSlim semaphore)
        {
            bool isCompleted=false;
            while (!isCompleted)
       {
           if(semaphore.Wait(500))
                {
                    try
                    {
                        Console.WriteLine("Task {0} locked the semaphor", Task.CurrentId);
                        Thread.Sleep(2000);
                    }
                    finally
                    {
                        Console.WriteLine("Task {0} releases the semaphor", Task.CurrentId);
                        semaphore.Release();
                        isCompleted = true;
                    }             
                }
                else
                {
                    Console.WriteLine("Task {0} not locked  the semaphor,await again", Task.CurrentId);
                }
       }
        }
  } 


0 0
原创粉丝点击