b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

多线程死锁的例子 学习线程(1)(2)

电脑杂谈  发布时间:2018-02-13 00:08:16  来源:网络整理

当有一个线程进入锁住的代码块是,是在外面加锁,这样剩下的线程只能等待当前线程执行完毕后释放锁,这样的话就保证了List变量在取值时不会被其他线程清除掉;尽管List是一个线程安全类,就是多线程操作该类时只有一个线程操作的类,但是这里仍然避免不了线程安全的问题,因为仍然控制不了操作的顺序,在清除后读取肯定会报错。

调用Monitor执行只能有一个线程运行的代码块时,仍有可能会抛出异常,但是有时候又不能终止进程,使用try{}catch{}包起来是个解决方式,那干脆再封装一次Monitor的方法,于是lock便出现了,则上述的例子可以改写为:

等价于:

当线程进入lock代码块时,将会调用Monitor.Enter()方法,退出代码块会调用Monitor.Exit()方法。另外,Monitor还提供了三个静态方法Monitor.Pulse(),Monitor.PulseAll()和Monitor.Wait() ,用来实现一种唤醒机制的同步。关于这三个方法的用法,可以参考MSDN,我这里也在学习中,就先不讲述了。虽说lock没有Monitor功能强大,但是使用确实方便,这里取舍就看实际需求了。

线程同步的方式还有很多,比如Mutex。还有很多的方法,以后用到的时候在研究吧。

Mutex:Mutex不具备Wait,Pulse,PulseAll的功能,因此,我们不能使用Mutex实现类似的唤醒的功能;不过Mutex有一个比较大的特点,Mutex是跨进程的,因此我们可以在同一台机器甚至远程的机器上的多个进程上使用同一个互斥体。

CLR线程池是.NET框架中很重要的一部分,不光能被开发人员使用,自身的很也是由线程池实现;我们在将任务委托给线程池的时候,是将该任务放到线程池的任务队列上,若线程池内存在空闲线程,则会将该任务委托给该线程,等待调度到CPU执行,若是没有空闲的线程且线程池所管理的线程数量还没有达到上限的时候,线程池便会创建新的Thread实体,否则,该任务会在队列中等待。

数量上限:在CLR 2.0 SP1之前的版本中,线程池中 默认最大的线程数量 = 处理器数 * 25, CLR 2.0 SP1之后就变成了默认最大线程数量 = 处理器数 * 250,线程上限可以改变,通过使用ThreadPool.GetMax+Threads和ThreadPool.SetMaxThreads方法,可以获取和设置线程池的最大线程数。

线程池的使用更简单一些:

多线程 死锁 cuda_发生死锁的例子_多线程死锁的例子

这里QueueUserWorkItem方法需要传入一个QueueUserWorkItem委托(带object类型的参数,无返回值),所以我们需要线程执行的任务需要带一个object的参数,并且QueueUserWorkItem方法加入时存在一个重载,可以在这里传入一个参数。

当然这里也可以使用Lambda表达式:

使用线程池并发执行任务同样会遇到线程安全的问题,一样需要进行同步,在涉及线程使用公共资源,Monitor、lock等方法与上述线程使用一样,同样能达到理想的效果,就不重复介绍了;但是对于控制执行顺序上,这个没有使用new线程来的自由。

程池中,没有Join方法,若想控制线程的执行顺序,我推荐使用主线程等待线程池任务执行完毕,阻塞主线程的方式,这里可以使用WaitHandle:

在这里,给线程池每个相关的线程都创建一个AutoResetEvent,在执行完毕之后分别把属于自己的AutoResetEvent变为非终止,WaitHandle使用WaitAll方法阻塞主线程、等待所有的AutoResetEvent事件变为true,另外WaitHandle还有一个WaitAny方法阻塞,不过是只要其中一个线程结束,就会继续运行,不再阻塞。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-74428-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 庄司宇芽香
      庄司宇芽香

      就是之前一直荒废着的鬼城的空房子

    • 李天琪
      李天琪

      是个男人就不会像这样的想法

    每日福利
    热点图片
    拼命载入中...