首页 > 学院 > 开发设计 > 正文

浅解多线程(二)之和尚们的那些事儿

2019-11-17 03:09:44
字体:
来源:转载
供稿:网友

浅解多线程(二)之和尚们的那些事儿

  • 浅解多线程(一)之线程入门起步

本文链接

  1. 确定多线程的结束时间,thread的IsAlive属性
  2. 线程优先级,thread的ThreadPRiority属性
  3. 线程通信之Monitor类
  4. 线程排队之Join
  5. 多线程互斥锁Mutex
  6. 信号量semaphore

确定多线程的结束时间,thread的IsAlive属性

在多个线程运行的背景下,了解线程什么时候结束,什么时候停止是很有必要的。

案例:老和尚念经计时,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();                    }                }            }        }

线程优先级,thread的ThreadPriority属性

线程优先级区别于线程占有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();                }            }        }

为啦方便期间,从这以后,我要用控制台程序演示,操控线程。

线程通信之Monitor类

如果,你的线程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 + "果真如此的话,还是方丈大师自己去吧!! 祝福啊  .... ");                        //交给主持
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表