未完待续

简介:

 微软的net framework类库保证了所有的静态方法是线程安全的,这意味着如果有2个线程同时调用一个静态方法,数据也不会出错。Framework类库必须这样设计,因为不可能让多个公司提供的程序集通过一个锁申请资源。Console类包含一个静态字段,Console很多方法通过内部对它的申请或者释放来保证同一时间只有一个线程访问console

准确的说,线程安全并不是意味着线程同步。一个线程安全方法意味两个线程同时访问一个数据时,数据不会出错。 System.Math 类有一个静态方法 Max实现如下:
public static Int32 Max(Int32 val1, Int32 val2) {
return (val1 < val2) ? val2 : val1;
}

 

该线程即使不加锁,也是线程安全的,因为Int32是一个值类型,两个Int32类型的值会被复制后传入Max方法,因此多个线程可以同时调用Max方法,每个线程只方法自己的数据,和别的线程互相隔离。

另一方面,FCL不保证实例方法线程安全,因为为所有的代码加锁为损害性能。事实上,如果每个实例方法需要获取锁和释放锁,那么最终你的应用程序在任何时间都只有一个线程在运行,这更加损害了性能。当一个线程构建一个对象,只有该线程能引用这个对象,其他线程都不能访问该对象,调用该实例方法的时候也不需要线程同步。然而,如果线程把对象放置在静态区,暴露了对象引用,作为参数传到ThreadPool.QueueUserWorkItem或者Task等等,并且这个对象可以同时被读写访问,那么就需要线程同步。

建议你自己的类库也遵循这种模式,让你所有的静态方法线程安全,不需要让你所有的实例方法线程安全。这种模式有一个注意的地方,如果实例方法的目的是协调线程,那么该实例方法需要线程安全。例如,一个线程能通过调用CancellationTokenSource的Cancel方法取消一个操作,另一个线程通过询问负责协调的CancellationToken类的IsCancellationRequested属性来侦测线程是否应该停止。这两个实例成员有一些特殊的线程同步代码来保证这两个线程的协调。

有两种线程同步结构可以直接在你的代码中使用:用户模式和内核模式。尽可能的使用用户模式结构,因为这种结构明显的比内核模式结构快,因为这种结构使用了专用的CPU指令来协调线程,这就意味着在硬件级别协调线程。这也意味使用用户模式结构,Windows操作系统无法侦测到线程阻塞。

 由于线程池线程在用户模式结构上的阻塞不被认为是阻塞,线程池也不会创建新的线程来替换这个临时被阻塞的线程,此外,这些CPU指令阻塞线程的时间极其短暂。听起来都不错吧?但是这也有一些负面的因素,只有Windows操作系统能内核可以停止一个线程,让它不用浪费CPU时间。用户模式下的线程可以被系统优先占取,但是此线程也会被再次调度。所以一个线程想要获得某些资源但是不能获得,将会空转,这将潜在的浪费CPU时间。





















本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/524531,如需转载请自行联系原作者


相关文章
|
2月前
第一篇文章
禁用不用的ip
15 0
|
算法 JavaScript Devops
2022年的第一篇总结
今年有个新的计划,就是每过一段时间,比如说两个月,对自己的工作和生活进行总结和反思。
|
机器学习/深度学习 人工智能 算法
我的第一篇博客--C++课程设计
前言 这是我的第一篇博客,内容便是最近所做的课程设计,之后也会每天和大家分享一下刷题笔记,以及AC后的代码,希望大家的批评指正,分享大家的一些观点和想法,希望和大家共同进步。
115 0
|
算法 关系型数据库 MySQL
第一篇博文——与诸位共勉
第一篇博文——与诸位共勉
179 1
第一篇博文——与诸位共勉
自己微信公众号开发的总结(待续)
自己微信公众号开发的总结(待续)
1186 0
看到几篇好的文章
总结和分析几种判断RecyclerView到达底部的方法 - 简书 几个方法属性介绍 computeVerticalScrollExtent()是当前屏幕显示的区域高度, computeVerticalScrollOffset() 是当前屏幕之前滑过的距离, computeVerticalScrollRange()是整个View控件的高度。
930 0