浅解多线程(一)之线程入门起步
在多个线程运行的背景下,了解线程什么时候结束,什么时候停止是很有必要的。
案例:老和尚念经计时,2本经书,2个和尚念,一人一本,不能撕破,最短时间念完,问老和尚们念完经书最短需要多长时间。
分析:首先在开始念经的时候给计时,记为A,最后在记下慢和尚念完经书时的时间,记为B。求B-A
代码:IsAlive属性:标识此线程已启动并且尚未正常终止或中止,则为 true,再念,没念完,努力中;否则为 false,念完啦,歇着。
//和尚1,和尚2 public Thread td1, td2; public void StarThread() { //开启一个线程执行Hello方法,即和尚1念菠萝菠萝蜜 ThreadStart ts = new ThreadStart(Hello); td1 = new Thread(ts); td1.Start(); } public void StarThread1() { //开启一个线程执行Welcome方法,即和尚2念大金刚经 ThreadStart ts = new ThreadStart(Welcome); td2 = new Thread(ts); td2.Start(); } public string sayh="", sayw=""; //菠萝菠萝蜜 public void Hello() { //念 sayh = "Hellow everyone ! "; } //大金刚经 public void Welcome() { //念 sayw = "Welcome to ShangHai ! "; //偷懒10秒 Thread.Sleep(10000); } protected void btn_StarThread_Click(object sender, EventArgs e) { //记时开始,预备念 Response.Write("开始念的时间: "+DateTime.Now.ToString() + "</br>"); //和尚1就位 StarThread(); //和尚2就位 StarThread1(); int i = 0; while (i == 0) { //判断线程的IsAlive属性 //IsAlive标识此线程已启动并且尚未正常终止或中止,则为 true;否则为 false。 //如果两个都为false说明,线程结束终止 if (!td1.IsAlive && !td2.IsAlive) { i++; if (i == 1) { //念得内容,绕梁三尺。 Response.Write("我们年的内容: "+(sayh + " + " + sayw) + "</br>"); Response.Write("念完时的时间: "+DateTime.Now.ToString()); Response.End(); } } } }
线程优先级区别于线程占有cpu时间的多少,当然优先级越高同等条件下占有的cpu时间越多。级别高的执行效率要高于级别低的。
优先级有5个级别:Lowest<BelowNormal<Normal<AboveNormal<Highest;默认为Normal。
案例:老和尚娶媳妇。佛祖说:你们3个和尚,清修刻苦,现特许你们娶媳妇啦,不过娶媳妇的只能是你们三个中间的一人。条件是我手中的经书谁能先念完,谁可以娶。
分析:和尚平时都很刻苦,各有特点,平时和尚1在lowest环境下念经,和尚2在normal环境下念经,和尚3在Highest环境下念经。
protected void btn_StarThread_Click(object sender, EventArgs e) { Write(); } //i为和尚1念的页数 //j为和尚2念的页数 //k为和尚3念的页数 //c为经书总页数 int i=0,j=0,k=0,c=10000000; //和尚1念经 public void Jsi() { while (i <= c) { i+=1; } } //和尚2念经 public void Jsj() { while (j <= c) { j+=1; } } //和尚3念经 public void Jsk() { while (k <= c) { k+=1; } } public void Write() { //开启线程计算i ThreadStart sti = new ThreadStart(Jsi); Thread tdi = new Thread(sti); //设置线程优先级为Lowest。和尚1在Lowest环境下念经 tdi.Priority = ThreadPriority.Lowest; //开启线程计算j ThreadStart stj = new ThreadStart(Jsj); Thread tdj = new Thread(stj); //设置线程优先级为Normal。和尚2在Normal环境下念经 tdj.Priority = ThreadPriority.Normal; //开启线程计算k ThreadStart stk = new ThreadStart(Jsk); Thread tdk = new Thread(stk); //设置线程优先级为Highest。和尚3在Highest环境下念经 tdk.Priority = ThreadPriority.Highest; //开始 tdj.Start(); tdk.Start(); tdi.Start(); int s = 0; while (s==0) { if (k > c) { s++; Response.Write("比赛结束,结果如下:</br></br>"); Response.Write("和尚1在Lowest环境下念经:" + i + "页</br>和尚2在Normal环境下念经:" + j + "页</br>和尚3在Highest环境下念经:" + k + "页</br></br>"); Response.Write("佛祖又说:你念或者不念,苍老师,就在那里!"); Response.End(); } } }
为啦方便期间,从这以后,我要用控制台程序演示,操控线程。
如果,你的线程A中运行锁内方法时候,需要去访问一个暂不可用资源B,可能在B上需耗费很长的等待时间,那么这时候你的线程A,将占用锁内资源,阻塞其它线程访问锁定内容,造成性能损失。你该怎么解决这样子的问题呢?这样,让A暂时放弃锁,停留在锁中的,允许其它线程访问锁,而等B资源可用时,通知A让他继续锁内的操作。是不是解决啦问题,这样就用到啦这段中的Monitor类,提供的几个方法:Wait(),Pulse(),PulseAll(),这几个方法只能在当前锁定中使用。
Wait():暂时中断运行锁定中线程操作,释放锁,时刻等待着通知复活。
Pulse():通知等待该锁线程队列中的第一个线程,此锁可用。
PulseAll():通知所有锁,此锁可用。
案例:嵩山少林和尚开会。主持人和尚主持会议会不停的上舞台讲话,方丈会出来宣布大会开始,弟子们开始讨论峨眉山怎么走。
分析:主持人一个线程,方丈一个线程,弟子们一个线程,主持人贯彻全场。
public class MutexSample { static void Main() { comm com = new comm(); com.dhThreads(); Console.ReadKey(); } } public class comm { //状态值:0时主持人和尚说,1时方丈说,2时弟子们说,3结束。 int sayFla; //主持人上台 int i = 0; public void zcrSay() { lock (this) { string sayStr; if (i == 0) { //让方丈说话 sayFla = 1; sayStr = Thread.CurrentThread.Name+"今晚,阳光明媚,多云转晴,方丈大师,程祥云而来,传扬峨眉一隅,情况如何,还请方丈闪亮登场。"; Console.WriteLine(sayStr); i++; //此时sayFla=1通知等待的方丈线程运行 Monitor.Pulse(this); //暂时锁定主持人,暂停到这里,释放this让其它线程访问 Monitor.Wait(this); } //被通知后,从上一个锁定开始运行到这里 if (i == 1) { //让弟子说话 sayFla = 2; sayStr = Thread.CurrentThread.Name + "看方丈那幸福的表情,徜徉肆恣,愿走的跟他去吧。下面请弟子们各抒己见"; Console.WriteLine(sayStr); i++; //此时sayFla=12通知等待的弟子线程运行 Monitor.Pulse(this); //暂时锁定主持人,暂停到这里,释放this让其它线程访问 Monitor.Wait(this); } //被通知后,从上一个锁定开始运行到这里 if (i == 2) { sayFla = 3; sayStr = Thread.CurrentThread.Name + "大会结束!方丈幸福!!苍老师你在哪里?!!放开那女孩 ..."; Console.WriteLine(sayStr); i++; Monitor.Wait(this); } } } //方丈上台 public void fzSay() { lock (this) { while (true) { if (sayFla != 1) { Monitor.Wait(this); } if (sayFla == 1) { Console.WriteLine(Thread.CurrentThread.Name + "蓝蓝的天空,绿绿的湖水,我看见,咿呀呀呀,看见一老尼,咿呀呀,在水一方。愿意来的一起来,不愿来的苍老师给你们放寺里。。咿呀呀,我走啦。。。"); //交给主持人 sayFla = 0; //通知主持人线程,this可用 Monitor.Pulse(this); } } } } //弟子上台 public void dzSay() { lock (this) { while (true) { if (sayFla != 2) { Monitor.Wait(this); } if (sayFla == 2) { Console.WriteLine(Thread.CurrentThread.Name + "果真如此的话,还是方丈大师自己去吧!! 祝福啊 .... "); //交给主持
新闻热点
疑难解答