一.为什么需要优先级--线程调度的问题

在现实生活中,优先级是一个很常见的现象:在火车站,如果你是孕妇,你是可以走进站中的专门绿色通道的,可以提前上火车以免拥挤;火警119匪警110出警的时候,都是人命关天的大事,是可以优先使用道路的,行人和车辆一律避让;在银行,如果你是白金VIP,也会有专门的绿色通道供你使用.从社会公平层面的优先级,到商业活动中的优先级,大家每天都生活在这样的环境之中,而且是按照这套游戏规则行事。

Windows是一个用户操作系统,在设计上遵循着稳定性为准则,也就是说他要与人类的思维方式保持一致,才能用得舒服,线程的优先级可以说就是这一原则下的产物.如果都让车辆在路上一直依次行驶,那么120到现场的时候,人都可能已经挂了;如果病毒一直抢占CPU,那杀毒软件也就没有什么卵用了。

这里需要注意现实生活中优先级与Windows中优先级的不同之处,现实生活中,我们可以通过新增资源(如增加窗口)优先处理高级别的业务,也可以通过对共同资源的调度(如110出警)来处理优化优先级高的业务。Windows则是在借鉴这些思路的时候进行了自己的一些改造,如调度队列、动态优先级调整等。

二.了解Windows的线程调度

Windows进化到现在,已经是一个时分和抢占式操作系统,它不同于实时操作系统,它通过动态地调整线程等待队列,从而确定线程使用cpu时间片的顺序。优先级高的线程有更大的概率排在队列的前面,同时获得更多数量的时间片,而不是更长时间的时间片。

线程如果被sleep掉、等待io时,会释放他所拥有的cpu,如果线程不是主动释放CPU,线程调度器会抢占该线程。如果优先级相同的多个线程等待使用CPU,则会使用一个循环调度规则来实现队列的先后顺序。

前面我们说过优先级是动态调整的,优先级低的不可能一直都是在等待,随着时间的运转,低优先级线程的优先级会提升,这样线程才有可能在等待结束时获得CPU。

再次强调,线程优先级只是提高了线程被调用的概率,并不是定义CPU调用线程的顺序,具体的工作就交给操作系统内部了。

三.C#中的线程优先级

C#中为我们提供了5个线程优先级别,如下所示:

线程默认的优先级为Normal,可以在线程的运行过程中修改线程的优先级,如下所示:

 static void Main(string[] args)
{
Thread th = new Thread(delegate() { Console.WriteLine("start a new thread"); });
Console.WriteLine(th.Priority);
th.Start();
th.Priority = ThreadPriority.Lowest;
Console.WriteLine(th.Priority);
Console.Read();
}

结果如下:

四.优先级反转

这里要用到锁的知识,对这块有疑问的可以先去大致了解下锁。

假设一种情况,线程A是高优先级线程,线程B是低优先级线程,线程B等啊等,终于等到自己,然后它锁住了一个资源R,然后线程A接手,但是它要用到R,R被锁,然后A只有等待B释放锁,然而B优先级低,它只有经过漫长的等待才能提高自己的优先级得到执行,而此时A仍然在等待B释放锁,从表而看线程A是有非常多的执行机会,但线程A并未执行任何代码,反而B一直在执行,那么线程A何时能够得到资源呢?不知道,原来的优先级设定也就失去了意义。这就是所谓的优先级反转。

那么,如何避免这一问题呢?这里给出一些建议。

1.锁的尺寸应该尽量小,就是使用小锁而非大锁,比如锁定字符串就是一个非常大的锁

2.锁的代码应该尽量短,这样锁定的时间就会尽量少

3.可以使用原子锁

使用优先级继承:也就是,高优先级进程TH在等待低优先级的线程TL占用的竞争资源时,为了使TH能够尽快获得调度运行,由操作系统把TL的优先级提高到TH的优先级,从而让TL以TH的优先级参与调度,尽快让TL执行并释放掉TH欲获得的竞争资源,然后TL的优先级调整到继承前的水平,此时TH可获得竞争资源而继承执行。优先级继承还可以存在传递性,也就是说TL还需要更低的低优先级线程TM的同步资源时,也会把TM的线程优先级拉高到TL,这要看各个操作系统的具体实现。

五.结尾

在做应用程序时,我们建议,尽量不去干预线程的优先级,把调度的顺序交给操作系统处理就好。

六.参考

《C#高级编程(第7版)》

博客  http://blog.csdn.net/feixiaoxing/article/details/7061582

博客  http://blog.csdn.net/thl789/article/details/617629

C#夯实基础之多线程三:线程的优先级的更多相关文章

  1. C#夯实基础之多线程二:主线程、前台线程与后台线程

    我们在<C#夯实基础之多线程一:初识多线程>一文中第二部分中指出,既然windows最终发展出了多线程模型,按理说,我们直接使用一个.NetFramework的线程类就可以直接撸代码了,但 ...

  2. python基础-12 多线程queue 线程交互event 线程锁 自定义线程池 进程 进程锁 进程池 进程交互数据资源共享

    Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...

  3. [19/04/08-星期一] 多线程_线程的优先级(Priority) 和 守护线程(Daemon)

    一.概念 1. 处于就绪状态的线程,会进入“就绪队列”等待JVM来挑选. 2. 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5. 3. 使用下列方法获得或设置线程对象的优先级. in ...

  4. Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  5. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

  6. JavaScript夯实基础系列(三):this

      在JavaScript中,函数的每次调用都会拥有一个执行上下文,通过this关键字指向该上下文.函数中的代码在函数定义时不会执行,只有在函数被调用时才执行.函数调用的方式有四种:作为函数调用.作为 ...

  7. Java基础学习——多线程之线程池

    1.线程池介绍     线程池是一种线程使用模式.线程由于具有空闲(eg:等待返回值)和繁忙这种不同状态,当数量过多时其创建.销毁.调度等都会带来开销.线程池维护了多个线程,当分配可并发执行的任务时, ...

  8. java基础之多线程三:多线程并发同步

    由于线程的执行是CPU随机调度的,比如我们开启10个线程,这10个线程并不是同时执行的,而是CPU快速的在这10个线程之间切换执行,由于切换速度极快使我们感觉同时执行罢了. 线程同步问题往往发生在多个 ...

  9. JAVA多线程(三) 线程池和锁的深度化

    github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...

随机推荐

  1. Netty学习笔记之一(Netty解析简单的Http Post Json 请求)

    一,HTTP解码器可能会将一个HTTP请求解析成多个消息对象. ch.pipeline().addLast(new HttpServerCodec()); ch.pipeline().addLast( ...

  2. 高介分类:核方法与支持向量机(SVM)

        数据模型:并不是简单地二维数据,多个维度或者对象的数据聚合起来      {           persion1's attr1:value1,...,persion1's attrN:va ...

  3. eclipse环境搭建

    百度经验http://jingyan.baidu.com/article/bea41d437a41b6b4c51be6c1.html 1.JAVA JDK 2.Andriod SDK eclipse里 ...

  4. Linux之sar命令介绍

    sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情 ...

  5. mybatis generator maven插件自动生成代码

    如果你正为无聊Dao代码的编写感到苦恼,如果你正为怕一个单词拼错导致Dao操作失败而感到苦恼,那么就可以考虑一些Mybatis generator这个差价,它会帮我们自动生成代码,类似于Hiberna ...

  6. 好用的wget命令从下载添加环境变量到各参数详解

    本文是因为(笔者使用的windows系统)使用过好几次wget后,始终存在各种细节问题,于是下定决定细致的研究一下,并记录下其中细节. 下载与安装 第一步:下载wget,网络地址:http://dow ...

  7. 【BZOJ-4698】Sandy的卡片 后缀数组

    4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 140  Solved: 55[Submit][Stat ...

  8. bootstrap 日期控件 bootstrap-datepicker

    http://www.bootcss.com/p/bootstrap-datetimepicker/

  9. AngularJS 细节

    AngularJS 表达式({{ expression }})类似于 AngularJS ng-bind 例子: <span>表达式</span> <div ng-app ...

  10. c# .Net并行和多线程编程之Task学习记录!

    任务Task和线程Thread的区别: 1.任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行. 2.任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线 ...