c# 多线程同步

线程同步:
   通过向线程授予对象锁来控制对对象的访问。对象锁提供限制访问代码块(通常称为临界区)的能力。当

一个线程拥有对象的锁时,其他任何线程都不能获取该锁。

lock 语句
   lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代

码,则它将一直等待(即被阻止),直到该对象被释放。

   lock的参数必须是基于引用类型的对象,不要是基本类型像bool,int什么的,这样根本不能同步,原因是

lock的参数要求是对象,如果传入int,势必要发生装箱操作,这样每次lock的都将是一个新的不同的对象

。最好避免使用public类型或不受程序控制的对象实例,因为这样很可能导致死锁。

---lock使用注意:
      1、如果一个类的实例是public的,最好不要lock(this)。因为使用你的类的人也许不知道你用了lock,

如果他new了一个实例,并且对这个实例上锁,就很容易造成死锁。

  2、如果MyType是public的,不要lock(typeof(MyType))

  3、永远也不要lock一个字符串

Monitor 方法:

Enter, TryEnter
  获取对象锁。此操作同样会标记临界区的开头。其他任何线程都不能进入临界区,除非它使用其他锁定对象

执行临界区中的指令。
Exit
  释放对象上的锁。此操作还标记受锁定对象保护的临界区的结尾。

TryEnter书写规范注意:

1.(推荐)
            //private static object tbobject = new object();
            Boolean OverTime = false;
            try
            {
                if (Monitor.TryEnter(tbobject, 2000))
                {
                    //-----
                }
                else
                {
                    OverTime = true;
                    //-----
                }
            }
            finally
            {
                if (!OverTime)
                    Monitor.Exit(tbobject);
            }

2.
            if (Monitor.TryEnter(tbobject, 2000))
            {
                try
                {
                    //-----
                }
                finally
                {
                    Monitor.Exit(tbobject);
                }
            }
            else
            {
                //-----
            }
{进程内的线程同步,推荐使用Monitor,因为Mutex类是win32封装的,所以它所需要的互操作转换更耗资源。}
(线程间通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。)

进程间同步: Mutex/Semaphore/(同步事件)AutoResetEvent和ManualResetEvent


Semaphore:限制可同时访问某一资源或资源池的线程数。
Semaphore 构造函数 (Int32, Int32, String)
initialCount:System.Int32
可以同时授予的信号量的初始请求数。
maximumCount:System.Int32
可以同时授予的信号量的最大请求数。
name:System.String
命名系统信号量对象的名称。

ManualResetEvent 允许线程通过发信号互相通信.通常,此通信涉及一个线程在其他线程进行之前必须完成

的任务。
       当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent

置于非终止状态。此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻

止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。

(AutoResetEvent   允许线程通过发信号互相通信.通常,此通信涉及线程需要独占访问的资源。)

EventWaitHandle.Reset 方法:将事件状态设置为非终止状态,导致线程阻止。

     线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 为非终止状态,则

线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用

     调用 Set 向 AutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在

等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。

如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。AutoResetEvent 将立即

释放线程并返回到非终止状态。


附录:相关文章:http://www.cnblogs.com/michaelxu/archive/2008/09/20/1293716.html
简述:归纳一下:C#线程同步的几种方法
一、volatile关键字
二、lock关键字
三、System.Threading.Interlocked
四、Monitor
五、Mutex
六、ReaderWriterLock
七、SynchronizationAttribute
八、MethodImplAttribute
九、同步事件和等待句柄

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值