一个程序至少有一个过程新匍京视频在线,一个程序至少有一个进程

  什么是线程安全:

新匍京视频在线 1😉

   3、线程同步

       执行下面的代码。窗口并从未登时执行
ThreadMethod方法输出循环数字,而是等待了三分钟之后才输出,因为线程起头履行的时候实施了Suspend()方法挂起。然后主线程休眠了3分钟未来又经过Resume()方法恢复生机了线程threadA。

新匍京视频在线 2

1
2
3
1、线程开的越多,内存占用越大
2、协调和管理代码的难度加大,需要CPU时间跟踪线程
3、线程之间对资源的共享可能会产生可不遇知的问题

出口结果:

      
Sleep()方法调已阻塞线程,是当前线程进入休眠状态,在蛰伏过程中占有系统内存不过不占用系统时间,当休眠期从此,继续执行,声明如下:
 

新匍京视频在线 3

新匍京视频在线 4

总结:

实施结果:

    static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod1), new object());    //参数可选
            Console.ReadKey();
        }

        public static void ThreadMethod1(object val)
        { 
            for (int i = 0; i <= 500000000; i++)
            {
                if (i % 1000000 == 0)
                {
                    Console.Write(Thread.CurrentThread.Name);
                } 
            } 
        }

Monitor.Wait是让眼前历程睡眠在临界资源上并释放独占锁,它只是等待,并不脱离,当等待停止,就要继续执行剩下的代码。

新匍京视频在线 5

多线程的先天不足:

线程池最多管理线程数量=“处理器数 *
250”。也就是说,如若你的机械为2个2核CPU,那么CLR线程池的容量默认上限便是1000

  好处:

施行结果:

上面是MSDN的解释。不清楚看代码:

举行结果:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ThreadTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            threadA.Name = "小A";
            threadA.Start();
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("[{2}] 我是:{0},我循环{1}次", Thread.CurrentThread.Name, i, DateTime.Now.ToString("HH:mm:ss.fff"));
                Thread.Sleep(300);         //休眠300毫秒              
            }
        }
    }
}

 public void ReleaseMutex()     释放 System.Threading.Mutex 一次。

新匍京视频在线 6

3、保证lock的靶子在表面无法修改才有含义,假使lock的目的在外表改变了,对此外线程就会通行,失去了lock的含义。

通过上边的推行结果,可以很领会的观看,多少个线程是在同时施行ThreadMethod这么些办法,这明显不合乎我们线程同步的渴求。大家对代码进行修改如下:

     1.3 多线程的创办

static void Main(string[] args)
        {
            Program pro1 = new Program();                    
            Program pro2 = new Program();                   
            Thread threadA = new Thread(pro1.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro2.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (this)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            }
        }

将方面的代码执行未来,可以明白的看来每便循环之间相距300飞秒的流年。

新匍京视频在线 7😉

 
 第两种处境:thread_second首先取得同步锁对象,首先实施到Monitor.PulseAll(monster),因为程序中从未索要等待信号进入就绪状态的线程,所以这一句代码没有意义,当执行到 Monitor.Wait(monster,
1000),自动将团结放逐到等候队列并在此间阻塞,1S
时间以后thread_second自动添加到就绪队列,线程thread_first得到monster对象锁,执行到Monitor.Wait(monster);时爆发围堵释放同步对象锁,线程thread_second执行,执行Monitor.PulseAll(monster)时通知thread_first。于是又起来率先种意况…

新匍京视频在线 8

实践结果:新匍京视频在线 9

新匍京视频在线 10新匍京视频在线 11

 

 2、线程池

通过线程池创立的线程默认为后台线程,优先级默认为Normal。

 区别以及哪些使用:

地方的代码中有五个线程,threadA,threadB和主线程,threadA优先级最高,threadB优先级最低。这一点从运行结果中也得以见到,线程B
偶尔会冒出在主线程和线程A前边。当有六个线程同时处于可举办境况,系统优先实施优先级较高的线程,但这只象征优先级较高的线程占有更多的CPU时间,并不代表早晚要先实施完优先级较高的线程,才会举行优先级较低的线程。

关于线程池的讲演请参见:

新匍京视频在线 12

static void Main(string[] args)
        {
            Program pro = new Program();
            Thread threadA = new Thread(pro.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (this)             //添加lock关键字
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            } 
        }

新匍京视频在线 13

新匍京视频在线 14

      
Sleep()方法调已阻塞线程,是眼前线程进入休眠状态,在蛰伏过程中占据系统内存可是不占用系统时间,当休眠期从此,继续执行,注明如下:
 

              {
                 //代码段
             } 
    就一样 
    Monitor.Enter(obj); 
                //代码段
    Monitor.Exit(obj);  

新匍京视频在线 15

1、概念

     
Lock关键字是Monitor的一种替换用法,lock在IL代码中会被翻译成Monitor. 

总结:

事先级越低表示CPU分配给该线程的时日片越少,执行时间就少

======

  windows系统是一个多线程的操作系统。一个先后至少有一个经过,一个历程至少有一个线程。进程是线程的容器,一个C#客户端程序先导于一个单独的线程,CLR(公共语言运行库)为该过程创建了一个线程,该线程称为主线程。例如当大家成立一个C#控制台程序,程序的进口是Main()函数,Main()函数是始于一个主线程的。它的成效紧如若发生新的线程和实施顺序。C#是一门辅助多线程的编程语言,通过Thread类创立子线程,引入using
System.Threading命名空间。 

大家透过添加了 lock(this)
{…}代码,查看执行结果实现了大家想要的线程同步要求。不过我们精通this表示最近类实例的自身,那么有这样一种情状,我们把需要拜访的措施所在的门类举行两个实例A和B,线程A访问实例A的艺术ThreadMethod,线程B访问实例B的不二法门ThreadMethod,这样的话还可以够达成线程同步的需求呢。

     
 单例情势就是确保在总体应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个取得该实例的全局访问点。但上边代码有一个尽人皆知的题材,这就是假诺多少个线程同时去赢得这一个目的实例,这。。。。。。。。

     static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "小A";  
            threadA.Start();  
            Thread.Sleep(3000);         //休眠3000毫秒      
            threadA.Resume();           //继续执行已经挂起的线程
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        {
            Thread.CurrentThread.Suspend();  //挂起当前线程
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i); 
            }
        }

新匍京视频在线 16

新匍京视频在线 17😉

      我们可以透过Monitor.TryEnter(monster,
1000),该形式也可以制止死锁的发生,我们下边的例子用到的是该办法的重载,Monitor.TryEnter(Object,Int32),。 

  1.0
线程的和进程的涉嫌以及优缺点**

为了印证方面所说的,我们第一看一段代码:  

先行级越高意味着CPU分配给该线程的时间片越多,执行时间就多

新匍京视频在线 18

总结:

Thread.IsBackground = false;//false:设置为前台线程,系统默认为前台线程。

     不可能锁定字符串,锁定字符串尤其危险,因为字符串被集体语言运行库
(CLR)“暂留”。
这意味整个程序中任何给定字符串都只有一个实例,就是这同一个目的表示了拥有运行的使用程序域的享无线程中的该文件。因而,只要在应用程序进程中的任何职务处具有同等内容的字符串上停放了锁,就将锁定应用程序中该字符串的持有实例。日常,最好避免锁定
public
类型或锁定不受应用程序lock块内决定的靶子实例。例如,假使该实例可以被公开访问,则
lock(this)
可能会有题目,因为不受控制的代码也说不定会锁定该目的。这说不定导致死锁,即六个或更多少个线程等待释放同一对象。出于同样的原委,锁定公共数据类型(比较于对象)也说不定造成问题。而且lock(this)只对当下目的有效,假若三个对象期间就达不到一块儿的效用。lock(typeof(Class))与锁定字符串一样,锁定的对象的功能域的限定太广了。

       其实在C# 2.0事后,
Suspent()和Resume()方法已经过时了。suspend()方法容易发生死锁。调用suspend()的时候,目的线程会停下来,但却仍旧有所在这此前拿到的锁定。此时,其他任何线程都不可以访问锁定的资源,除非被”挂起”的线程復苏运行。对其他线程来说,即便它们想重操旧业目标线程,同时又意欲利用其他一个锁定的资源,就会招致死锁。所以不应当运用suspend()。

新匍京视频在线 19😉

新匍京视频在线 20

  3.0
使用Mutex类实现
线程同步

 

新匍京视频在线 21😉

先是接纳new
Thread()创造出新的线程,然后调用Start方法使得线程进入就绪状态,得到系统资源后就推行,在实践进程中可能有等待、休眠、死亡和围堵四种意况。正常执行完毕时间片后重临到就绪状态。假若调用Suspend方法会进入等待状态,调用Sleep或者碰着进程同步使用的锁机制而休眠等待。具体过程如下图所示:

private static object obj = new object();
        static void Main(string[] args)
        {
            Program pro1 = new Program();                    
            Program pro2 = new Program();                   
            Thread threadA = new Thread(pro1.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro2.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (obj)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            }
        }
static void Main(string[] args)
        {                
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "A";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "B";
            threadA.Start();
            threadB.Start();
            Thread.CurrentThread.Name = "C";
            ThreadMethod();
            Console.ReadKey();
        }
        static object obj = new object();
        public static void ThreadMethod()
        {
            bool flag = Monitor.TryEnter(obj, 1000);   //设置1S的超时时间,如果在1S之内没有获得同步锁,则返回false
        //上面的代码设置了锁定超时时间为1秒,也就是说,在1秒中后,
       //lockObj还未被解锁,TryEntry方法就会返回false,如果在1秒之内,lockObj被解锁,TryEntry返回true。我们可以使用这种方法来避免死锁
            try
            {
                if (flag)
                {
                    for (int i = 0; i < 500; i++)
                    {
                        Console.Write(Thread.CurrentThread.Name); 
                    }
                }
            }
            catch(Exception ex)
            {

            }
            finally
            {
                if (flag)
                    Monitor.Exit(obj);
            } 
        } 

 

新匍京视频在线 22

    static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod1), new object());    //参数可选
            Console.ReadKey();
        }

        public static void ThreadMethod1(object val)
        { 
            for (int i = 0; i <= 500000000; i++)
            {
                if (i % 1000000 == 0)
                {
                    Console.Write(Thread.CurrentThread.Name);
                } 
            } 
        }

        2.2.5 Suspent()和Resume()方法

代码示例:

新匍京视频在线 23

   
下边的代码创设了一个子线程,作为程序的入口mian()函数所在的线程即为主线程,我们经过Thread类来创制子线程,Thread类有 ThreadStart 和
ParameterizedThreadStart类型的信托参数,我们也得以一贯写方法的名字。线程执行的办法可以传递参数(可选),参数的系列为object,写在Start()里。

新匍京视频在线 24

新匍京视频在线 25新匍京视频在线 26

1
2
3
1、线程开的越多,内存占用越大
2、协调和管理代码的难度加大,需要CPU时间跟踪线程
3、线程之间对资源的共享可能会产生可不遇知的问题

Wait(object)方法:释放对象上的锁并阻止当前线程,直到它再也拿到该锁,该线程进入等待队列。
 Pulse方法:只有锁的眼前主人可以接纳 Pulse 向等待对象发出信号,当前享有指定对象上的锁的线程调用此办法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被挪动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不必然是收纳到脉冲的线程)将得到该锁。
另外

  2.2.1 Abort()方法

  首要常用的多少个方法:

  好处:

      我们可以透过Monitor.TryEnter(monster,
1000),该情势也可以避免死锁的发出,大家下面的例证用到的是该办法的重载,Monitor.TryEnter(Object,Int32),。 

class Program
 {
        //我们的控制台程序入口是main函数。它所在的线程即是主线程
        static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法
            thread.Name = "子线程";
            //thread.Start("王建");                       //在此方法内传递参数,类型为object,发送和接收涉及到拆装箱操作
            thread.Start(); 
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter) //方法内可以有参数,也可以没有参数
        {
            Console.WriteLine("{0}开始执行。", Thread.CurrentThread.Name);
        }
  }

新匍京视频在线 27😉

lock(this) 锁定 当前实例对象,如果有多个类实例的话,lock锁定的只是当前类实例,对其它类实例无影响。所有不推荐使用。 
lock(typeof(Model))锁定的是model类的所有实例。 
lock(obj)锁定的对象是全局的私有化静态变量。外部无法对该变量进行访问。 
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。 
所以,lock的结果好不好,还是关键看锁的谁,如果外边能对这个谁进行修改,lock就失去了作用。所以一般情况下,使用私有的、静态的并且是只读的对象。

新匍京视频在线 28😉

  
   Abort方法可以通过跑出ThreadAbortException异常中止线程,而利用ResetAbort方法可以裁撤中止线程的操作,下边通过代码演示使用 ResetAbort方法。

    Enter(Object) 在指定对象上收获排他锁。

     
常用的章程有多个,Monitor.Enter(object)方法是赢得锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的六个办法,在采取过程中为了制止获取锁之后因为相当,致锁不可能自由,所以需要在try{}
catch(){}之后的finally{}结构体中放出锁(Monitor.Exit())。

新匍京视频在线 29😉

    static void Main(string[] args)
        {
            Thread[] thread = new Thread[3];
            for (int i = 0; i < 3; i++)
            {
                thread[i] = new Thread(ThreadMethod1);
                thread[i].Name = i.ToString();
            }
            for (int i = 0; i < 3; i++)
            {
                thread[i].Start();
            }
            Console.ReadKey(); 
        } 

        public static void ThreadMethod1(object val)
        {
            mutet.WaitOne();    //获取锁
            for (int i = 0; i < 500; i++)
            {
                Console.Write(Thread.CurrentThread.Name); 
            } 
            mutet.ReleaseMutex();  //释放锁
        }

   线程有可能和任何线程共享一些资源,比如,内存,文件,数据库等。当几个线程同时读写同一份共享资源的时候,可能会唤起顶牛。那时候,大家需要引入线程“同步”机制,即诸君线程之间要有个先来后到,无法一窝蜂挤上去抢作一团。线程同步的真实性意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:多少个线程之间要排队,一个一个对共享资源举行操作,而不是还要展开操作。

  1.缩小在成立和销毁线程上所花的年月以及系统资源的开销 
 
2.如不使用线程池,有可能导致系统创制大气线程而导致消耗完系统内存以及”过度切换”。

   
  上边介绍了介绍了平日应用的大部分的多线程的例子,但在实际上付出中运用的线程往往是大度的和越来越复杂的,这时,每一次都创建线程、启动线程。从性质上来讲,这样做并不可以(因为每使用一个线程就要成立一个,需要占用系统开发);从操作上来讲,每趟都要启动,相比较勤奋。为此引入的线程池的定义。

static void Main(string[] args)
        {                
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "A";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "B";
            threadA.Priority = ThreadPriority.Highest;
            threadB.Priority = ThreadPriority.BelowNormal;
            threadB.Start();
            threadA.Start();
            Thread.CurrentThread.Name = "C";
            ThreadMethod(new object());
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        {
            for (int i = 0; i < 500; i++)
            { 
                Console.Write(Thread.CurrentThread.Name); 
            }
        }

新匍京视频在线 30😉

 public virtual bool WaitOne()   阻止当前线程,直到当前
System.Threading.WaitHandle 收到信号获取互斥锁。

  使用实例:

        Wait 和 Pulse 方法必须写在 Monitor.Enter
和Moniter.Exit 之间。

Thread.IsBackground = false;//false:设置为前台线程,系统默认为前台线程。

一直上代码来看效果:

    TryEnter(Object, Boolean)
尝试得到指定对象上的排他锁,并机关安装一个值,提示是否拿走了该锁。

咱俩队代码举办改动:

率先程序中有六个线程,ThreadA、ThreadB、主线程,首先大家见到主线程和ThreadB线程阻塞,ThreadA先实施,而主线程和ThreadB线程则还要履行了。

  1.0 线程的和过程的关系以及优缺点**

TryEnter(Object)TryEnter()
方法在品味拿到一个目的上的显式锁方面和 Enter()方法类似。可是,它不像Enter()方法这样会阻塞执行。如若线程成功进去重点区域那么TryEnter()方法会重临true. 和试图拿走指定对象的排他锁。看上面代码演示:

新匍京视频在线 31

        public static void Sleep(TimeSpan timeout);          //时间段
        public static void Sleep(int millisecondsTimeout);   //毫秒数

     

新匍京视频在线 32😉

新匍京视频在线 33

新匍京视频在线 34😉

事先级越高意味着CPU分配给该线程的时刻片越多,执行时间就多

比方有一个前台线程未脱离,进程就不会停下!即说的就是程序不会倒闭!(即在资源管理器中得以看出进程未截至。)

新匍京视频在线 35

 

在怎样情状下使用线程池? 

通过翻看执行结果。会发觉代码实现了我们的需求,五个线程按顺序执行了。那么 lock(this)
和lock(Obj)有哪些界别吧? 我们再看一个示范代码:

 输输出结果: 新匍京视频在线 36

  什么是线程安全:

     static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "小A";  
            threadA.Start();  
            Thread.Sleep(3000);         //休眠3000毫秒      
            threadA.Resume();           //继续执行已经挂起的线程
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        {
            Thread.CurrentThread.Suspend();  //挂起当前线程
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i); 
            }
        }

推行结果:

代码示例:

新匍京视频在线 37😉

新匍京视频在线 38

新匍京视频在线 39😉

 

static void Main(string[] args)
        {                
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "A";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "B";
            threadA.Priority = ThreadPriority.Highest;
            threadB.Priority = ThreadPriority.BelowNormal;
            threadB.Start();
            threadA.Start();
            Thread.CurrentThread.Name = "C";
            ThreadMethod(new object());
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        {
            for (int i = 0; i < 500; i++)
            { 
                Console.Write(Thread.CurrentThread.Name); 
            }
        }

多线程的缺点:

新匍京视频在线 40😉

static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            thread.Name = "小A";
            thread.Start();  
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter)  
        {
            Console.WriteLine("我是:{0},我要终止了", Thread.CurrentThread.Name);
            //开始终止线程
            Thread.CurrentThread.Abort();
            //下面的代码不会执行
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
            }
        }

施行结果:

  实例代码: 

新匍京视频在线 41😉

透过修改后的代码。加了一个
lock(obj)代码块。这样就可知落实协同了,即便不是很通晓的话,大家看前面继续上课~

     
Lock关键字是Monitor的一种替换用法,lock在IL代码中会被翻译成Monitor. 

/// <summary>
    /// 怪物类
    /// </summary>
    internal class Monster
    {
        public int Blood { get; set; }
        public Monster(int blood)
        {
            this.Blood = blood;
            Console.WriteLine("我是怪物,我有{0}滴血",blood);
        }
    }

?

              {
                 //代码段
             } 
    就同样 
    Monitor.Enter(obj); 
                //代码段
    Monitor.Exit(obj);  

新匍京视频在线 42😉

下面是MSDN的表明。不了解看代码:

线程池最多管理线程数量=“处理器数 *
250”。也就是说,如若您的机器为2个2核CPU,那么CLR线程池的容量默认上限便是1000

新匍京视频在线 43

   
  Mutex的崛起特点是可以跨应用程序域边界对资源开展垄断访问,即可以用来共同不同进程中的线程,这种意义自然那是以牺牲更多的系统资源为代价的。

2、lock推荐的做法是利用静态的、只读的、私有的目的。

View Code

新匍京视频在线 44

咱俩队代码举行改动:

static void Main(string[] args)
        {
            Program pro = new Program();
            Thread threadA = new Thread(pro.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (this)             //添加lock关键字
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            } 
        }

    TryEnter(Object) 试图获取指定对象的排他锁。

   
  Mutex的凸起特点是可以跨应用程序域边界对资源拓展垄断访问,即可以用来共同不同进程中的线程,这种效应自然这是以献身更多的系统资源为代价的。

1、lock的是必须是引用类型的目的,string类型除外。

2、线程的基本操作

   
 
C#中的线程分为前台线程和后台线程,线程创设时不做设置默认是前台线程。即线程属性IsBackground=false。

    
 Join方法首假使用来阻塞调用线程,直到某个线程终止或通过了点名时间结束。官方的演说相比干燥,通俗的说就是开创一个子线程,给它加了这一个办法,另外线程就会半途而废实施,直到这多少个线程执行完截止才去履行(包括主线程)。她的方法表明如下:

新匍京视频在线 45

新匍京视频在线 46

     
常用的法门有两个,Monitor.Enter(object)方法是拿到锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的六个办法,在运用过程中为了制止获取锁之后因为异常,致锁不能自由,所以需要在try{}
catch(){}之后的finally{}结构体中放出锁(Monitor.Exit())。

 

    1.单个任务处理的时日相比较短 
    2.亟待处理的天职的多少大 

    TryEnter(Object) 试图获取指定对象的排他锁。

新匍京视频在线 47😉

 

通过改动后的代码。加了一个
lock(obj)代码块。这样就可以实现协同了,假诺不是很明亮的话,大家看前边继续上课~

static void Main(string[] args)
        {
            Program pro1 = new Program();                    
            Program pro2 = new Program();                   
            Thread threadA = new Thread(pro1.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro2.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (this)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            }
        }

新匍京视频在线 48😉

新匍京视频在线 49

     static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            thread.Name = "小A";
            thread.Start();  
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter)  
        {
            try
            {
                Console.WriteLine("我是:{0},我要终止了", Thread.CurrentThread.Name); 
         //开始终止线程
                Thread.CurrentThread.Abort();
            }
            catch(ThreadAbortException ex)
            {
                Console.WriteLine("我是:{0},我又恢复了", Thread.CurrentThread.Name);
         //恢复被终止的线程
                Thread.ResetAbort();
            }
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
            }
        }

大家通过添加了 lock(this)
{…}代码,查看执行结果实现了我们想要的线程同步要求。不过咱们精通this表示目前类实例的自我,那么有这么一种意况,我们把需要拜访的格局所在的连串举办四个实例A和B,线程A访问实例A的方法ThreadMethod,线程B访问实例B的法子ThreadMethod,这样的话还是可以够达标线程同步的需要吗。

static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        { 
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                Thread.Sleep(300);
            }
        }

Monitor.Wait是让眼前历程睡眠在临界资源上并释放独占锁,它只是等待,并不脱离,当等待截止,就要继续执行剩下的代码。

        Wait
和 Pulse 方法必须写在 Monitor.Enter 和Moniter.Exit
之间**
。**

  3.1 使用Monitor类实现线程同步      

出口结果:

  紧要常用的四个措施:

新匍京视频在线 50

 

新匍京视频在线 51😉

      2.2.4 join()方法

新匍京视频在线 52😉

新匍京视频在线 53

新匍京视频在线 54

新匍京视频在线 55

static void Main(string[] args)
        {
            Class1 pro1 = new Class1();
            Class1 pro2 = new Class1();
            Thread threadA = new Thread(pro1.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro2.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }

//另外新建一个类
 public class Class1
    {

        private static object obj = new object();

        public void ThreadMethod(object parameter)
        {
            lock (obj)   // 也可以使用 lock (typeof(Class1)) 方法来锁定
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            }
        }
    }

新匍京视频在线 56

优先级越低表示CPU分配给该线程的年华片越少,执行时间就少

新匍京视频在线 57

新匍京视频在线 58

static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public static void ThreadMethod(object parameter)
        { 
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                Thread.Sleep(300);
            }
        }

     lock(obj)

经过查阅执行结果。会发觉代码实现了大家的急需。那么 lock(this)
和lock(Obj)有咋样界别吧? 

新匍京视频在线 59😉

新匍京视频在线 60

      2.2.4 join()方法

新匍京视频在线 61

2.1 线程的有关属性

    Exit(Object) 释放指定对象上的排他锁。 

     1.3 多线程的开创

新匍京视频在线 62

  实例代码: 

Enter(Object)的用法很简短,看代码 

class Program
 {
        //我们的控制台程序入口是main函数。它所在的线程即是主线程
        static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法
            thread.Name = "子线程";
            //thread.Start("王建");                       //在此方法内传递参数,类型为object,发送和接收涉及到拆装箱操作
            thread.Start(); 
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter) //方法内可以有参数,也可以没有参数
        {
            Console.WriteLine("{0}开始执行。", Thread.CurrentThread.Name);
        }
  }

  只要在应用程序中有五个线程在运作,但局部线程比另一部分线程首要,这种意况下可以在一个经过中为不同的线程指定不同的预先级。线程的预先级能够通过Thread类Priority属性设置,Priority属性是一个ThreadPriority型枚举,列举了5个优先等级:Above诺玛l、Below诺玛(Norma)l、Highest、Lowest、Normal。公共语言运行库默认是Normal类型的。见下图:

将地点的代码执行未来,可以知道的观望每便循环之间离开300纳秒的时刻。

 区别以及哪些采用:

新匍京视频在线 63😉

实践结果:和我们想像的均等,下边的巡回没有被执行新匍京视频在线 64

新匍京视频在线 65😉

  线程安全是指在当一个线程访问该类的某部数据时,举行保障,其他线程不可以举办访问直到该线程读取完,其他线程才可拔取。不会出现数量不平等或者数额污染。

 public void ReleaseMutex()  
  释放 System.Threading.Mutex 一次。

新匍京视频在线 66

新匍京视频在线 67

新匍京视频在线 68

3.1
使用Monitor类实现线程同步 
     

 

2、lock推荐的做法是运用静态的、只读的、私有的靶子。

*     不能锁定字符串,锁定字符串尤其危险,因为字符串被集体语言运行库
(CLR)“暂留”。
这表示任何程序中任何给定字符串都只有一个实例,就是这同一个对象表示了具备运行的应用程序域的所无线程中的该文件。因而,只要在应用程序进程中的任何地点处具有同样内容的字符串上停放了锁,就将锁定应用程序中该字符串的富有实例。通常,最好防止锁定
public
类型或锁定不受应用程序控制的目的实例。例如,假若该实例可以被公开访问,则
lock(this)
可能会有问题,因为不受控制的代码也可能会锁定该对象。那恐怕引致死锁,即三个或更两个线程等待释放同一对象。出于同样的来头,锁定公共数据类型(相比较于对象)也恐怕造成问题。而且lock(this)只对当下目的有效,假设五个对象期间就达不到一同的效率。lock(typeof(Class))与锁定字符串一样,范围太广了。*

 

     static void Main(string[] args)
        {                
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "A";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "B";
            threadA.Start();
            threadB.Start();
            Thread.CurrentThread.Name = "C";
            ThreadMethod();
            Console.ReadKey();
        }
        static object obj = new object();
        public static void ThreadMethod()
        {
            Monitor.Enter(obj);      //Monitor.Enter(obj)  锁定对象
            try
            {
                for (int i = 0; i < 500; i++)
                {
                    Console.Write(Thread.CurrentThread.Name); 
                }
            }
            catch(Exception ex){   }
            finally
            { 
                Monitor.Exit(obj);  //释放对象
            } 
        } 

新匍京视频在线 69😉

新匍京视频在线 70

在怎么着状态下使用线程池? 

线程和其他常见的类一样,有着许多性质和方法,参考下表:

新匍京视频在线 71

static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法
            thread.Name = "子线程"; 
            thread.Start();
            StringBuilder threadInfo = new StringBuilder();
            threadInfo.Append(" 线程当前的执行状态: " + thread.IsAlive);
            threadInfo.Append("\n 线程当前的名字: " + thread.Name);
            threadInfo.Append("\n 线程当前的优先级: " + thread.Priority);
            threadInfo.Append("\n 线程当前的状态: " + thread.ThreadState);
            Console.Write(threadInfo);
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter)  
        {
            Console.WriteLine("{0}开始执行。", Thread.CurrentThread.Name);
        }
/// <summary>
    /// 玩家类
    /// </summary>
    internal class Play
    {
        /// <summary>
        /// 攻击者名字
        /// </summary>
        public string Name { get; set; } 
        /// <summary>
        /// 攻击力
        /// </summary>
        public int Power{ get; set; }
        /// <summary>
        /// 法术攻击
        /// </summary>
        public void magicExecute(object monster)
        {
            Monster m = monster as Monster;
            Monitor.Enter(monster);
            while (m.Blood>0)
            {
                Monitor.Wait(monster);
                Console.WriteLine("当前英雄:{0},正在使用法术攻击打击怪物", this.Name);
                if(m.Blood>= Power)
                {
                    m.Blood -= Power;
                }
                else
                {
                    m.Blood = 0;
                }
                Thread.Sleep(300);
                Console.WriteLine("怪物的血量还剩下{0}", m.Blood);
                Monitor.PulseAll(monster);
            }
            Monitor.Exit(monster);
        }
        /// <summary>
        /// 物理攻击
        /// </summary>
        /// <param name="monster"></param>
        public void physicsExecute(object monster)
        {
            Monster m = monster as Monster;
            Monitor.Enter(monster);
            while (m.Blood > 0)
            {
                Monitor.PulseAll(monster);
                if (Monitor.Wait(monster, 1000))     //非常关键的一句代码
                {
                    Console.WriteLine("当前英雄:{0},正在使用物理攻击打击怪物", this.Name);
                    if (m.Blood >= Power)
                    {
                        m.Blood -= Power;
                    }
                    else
                    {
                        m.Blood = 0;
                    }
                    Thread.Sleep(300);
                    Console.WriteLine("怪物的血量还剩下{0}", m.Blood);
                }
            }
            Monitor.Exit(monster);
        }
    }

为什么要落实同台啊,下边的事例大家拿出名的单例情势以来呢。看代码

  windows系统是一个多线程的操作系统。一个主次至少有一个历程,一个历程至少有一个线程。进程是线程的器皿,一个C#客户端程序起始于一个单身的线程,CLR(公共语言运行库)为该过程创立了一个线程,该线程称为主线程。例如当大家创立一个C#控制台程序,程序的输入是Main()函数,Main()函数是始于一个主线程的。它的效应重尽管发出新的线程和实践顺序。C#是一门帮忙多线程的编程语言,通过Thread类创设子线程,引入using
System.Threading命名空间。 

     Abort()方法用来终止线程,调用此方法强制截止正在实践的线程,它会抛出一个ThreadAbortException非常从而导致目的线程的平息。下边代码演示:

    static void Main(string[] args)
        {
            //怪物类
            Monster monster = new Monster(1000);
            //物理攻击类
            Play play1 = new Play() { Name = "无敌剑圣", Power = 100 };
            //魔法攻击类
            Play play2 = new Play() { Name = "流浪法师", Power = 120 };
            Thread thread_first = new Thread(play1.physicsExecute);    //物理攻击线程
            Thread thread_second = new Thread(play2.magicExecute);     //魔法攻击线程
            thread_first.Start(monster);
            thread_second.Start(monster);
            Console.ReadKey();
        }

新匍京视频在线 72

新匍京视频在线 73😉

static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            threadA.Name = "小A";
            Thread threadB = new Thread(ThreadMethod);     //执行的必须是无返回值的方法  
            threadB.Name = "小B";
            threadA.Start();
       //threadA.Join();      
            threadB.Start();
       //threadB.Join();

            for (int i = 0; i < 10; i++)
            { 
                Console.WriteLine("我是:主线程,我循环{1}次", Thread.CurrentThread.Name, i);
                Thread.Sleep(300);          //休眠300毫秒                                                
            }
            Console.ReadKey();
        } 
        public static void ThreadMethod(object parameter)  
        { 
            for (int i = 0; i < 10; i++)
            { 
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
                Thread.Sleep(300);         //休眠300毫秒              
            }
        }
 public void Join();
 public bool Join(int millisecondsTimeout);    //毫秒数
 public bool Join(TimeSpan timeout);       //时间段

  使用实例:

 

 首先大家定义一个攻击类,

static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法
            thread.Name = "子线程"; 
            thread.Start();
            StringBuilder threadInfo = new StringBuilder();
            threadInfo.Append(" 线程当前的执行状态: " + thread.IsAlive);
            threadInfo.Append("\n 线程当前的名字: " + thread.Name);
            threadInfo.Append("\n 线程当前的优先级: " + thread.Priority);
            threadInfo.Append("\n 线程当前的状态: " + thread.ThreadState);
            Console.Write(threadInfo);
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter)  
        {
            Console.WriteLine("{0}开始执行。", Thread.CurrentThread.Name);
        }

2.2 线程的有关操作

 

     static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            thread.Name = "小A";
            thread.Start();  
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter)  
        {
            try
            {
                Console.WriteLine("我是:{0},我要终止了", Thread.CurrentThread.Name); 
         //开始终止线程
                Thread.CurrentThread.Abort();
            }
            catch(ThreadAbortException ex)
            {
                Console.WriteLine("我是:{0},我又恢复了", Thread.CurrentThread.Name);
         //恢复被终止的线程
                Thread.ResetAbort();
            }
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
            }
        }

新匍京视频在线 74新匍京视频在线 75

新匍京视频在线 76

新匍京视频在线 77

    Pulse 通知等待队列中的线程锁定目的情形的更改。

  2.2.2 ResetAbort()方法

 2、线程池

新匍京视频在线 78😉

 Monitor.Wait和Monitor()Pause()

    2.2.6 线程的先行级

     现在我们把代码中的
 ThreadA.join()方法注释撤除,首先程序中有五个线程,ThreadA、ThreadB和主线程,首先主线程先阻塞,然后线程ThreadB阻塞,ThreadA先实施,执行完毕之后ThreadB接着执行,最终才是主线程执行。

  3.0
使用Lock关键字贯彻
线程同步 

 public void Join();
 public bool Join(int millisecondsTimeout);    //毫秒数
 public bool Join(TimeSpan timeout);       //时间段

     1.1 前台线程和后台线程

http://www.cnblogs.com/JeffreyZhao/archive/2009/07/22/thread-pool-1-the-goal-and-the-clr-thread-pool.html

新匍京视频在线 79

实施结果:

    Exit(Object) 释放指定对象上的排他锁。 

   
下边的代码创立了一个子线程,作为程序的入口mian()函数所在的线程即为主线程,大家透过Thread类来创设子线程,Thread类有 ThreadStart 和
ParameterizedThreadStart类型的寄托参数,大家也可以直接写方法的名字。线程执行的不二法门可以传递参数(可选),参数的类型为object,写在Start()里。

       其实在C# 2.0之后,
Suspent()和Resume()方法已经过时了。suspend()方法容易暴发死锁。调用suspend()的时候,目标线程会停下来,但却依然有所在这前面拿到的锁定。此时,其他任何线程都不可能访问锁定的资源,除非被”挂起”的线程复苏运行。对其他线程来说,如若它们想重操旧业目的线程,同时又打算动用另外一个锁定的资源,就会促成死锁。所以不应当采用suspend()。

    static void Main(string[] args)
        {
            //怪物类
            Monster monster = new Monster(1000);
            //物理攻击类
            Play play1 = new Play() { Name = "无敌剑圣", Power = 100 };
            //魔法攻击类
            Play play2 = new Play() { Name = "流浪法师", Power = 120 };
            Thread thread_first = new Thread(play1.physicsExecute);    //物理攻击线程
            Thread thread_second = new Thread(play2.magicExecute);     //魔法攻击线程
            thread_first.Start(monster);
            thread_second.Start(monster);
            Console.ReadKey();
        }

地点的代码中有五个线程,threadA,threadB和主线程,threadA优先级最高,threadB优先级最低。这点从运行结果中也可以见见,线程B
偶尔会油然则生在主线程和线程A前边。当有多少个线程同时高居可实施情形,系统优先执行优先级较高的线程,但这只表示优先级较高的线程占有更多的CPU时间,并不代表一定要先举办完优先级较高的线程,才会实施优先级较低的线程。

万一有一个前台线程未脱离,进程就不会终止!即说的就是程序不会倒闭!(即在资源管理器中得以看出进程未竣工。)

lock(this) 锁定 当前实例对象,如果有多个类实例的话,lock锁定的只是当前类实例,对其它类实例无影响。所有不推荐使用。 
lock(typeof(Model))锁定的是model类的所有实例。 这里的Model是指某个类名。
lock(obj)锁定的对象是全局的私有化静态变量。外部无法对该变量进行访问。 
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。 
所以,lock的结果好不好,还是关键看锁的谁,如果外边能对这个谁进行修改,lock就失去了作用。
所以,一般情况下,使用私有的、静态的并且是只读的对象。

俺们会发觉,线程又从不兑现同台了!lock(this)对于这种情况是可怜的!所以需要我们对代码举行修改!修改后的代码如下: 

 

  2.2.2 ResetAbort()方法

2.2 线程的有关操作

有关线程池的诠释请参见:

 

    PulseAll 公告所有的等候线程对象情况的改变。

  2.2.3 Sleep()方法 

  1. thread_first首先取得同步对象的锁,当执行到 Monitor.Wait(monster);时,thread_first线程释放自己对一起对象的锁,流放自己到等候队列,直到自己再也取得锁,否则一贯不通。
  2. 而thread_second线程一最先就竞争同步锁所以处于就绪队列中,这时候thread_second直接从稳妥队列出来拿到了monster对象锁,先导履行到Monitor.PulseAll(monster)时,发送了个Pulse信号。
  3. 这时候thread_first接收到信号进入到妥善状态。然后thread_second继续往下实施到
    Monitor.Wait(monster,
    1000)时,这是一句异常紧要的代码,thread_second将团结放逐到等候队列并释放自我对同步锁的独占,该等待安装了1S的超时值,当B线程在1S以内没有重新赢拿到锁自动添加到就绪队列。
  4. 这时thread_first从Monitor.Wait(monster)的不通截至,重回true。起始履行、打印。执行下一行的Monitor.Pulse(monster),这时候thread_second倘使1S的时光还没过,thread_second接收到信号,于是将自己添加到就绪队列。
  5. thread_first的一道代码块停止以后,thread_second再度赢得执行权, Monitor.Wait(m_smplQueue,
    1000)重回true,于是连续从该代码处往下实施、打印。当再次实施到Monitor.Wait(monster,
    1000),又起来了步骤3。
  6. 梯次轮回。。。。

实施结果:

1、lock的是必须是引用类型的对象,string类型除外。

新匍京视频在线 80😉

新匍京视频在线 81

 

新匍京视频在线 82

看实践结果:

     1.1 前台线程和后台线程

通过线程池成立的线程默认为后台线程,优先级默认为诺玛l。

推行代码:

新匍京视频在线 83😉

新匍京视频在线 84

新匍京视频在线 85😉

    2.2.6 线程的事先级

static void Main(string[] args)
        {                
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "A";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "B";
            threadA.Start();
            threadB.Start();
            Thread.CurrentThread.Name = "C";
            ThreadMethod();
            Console.ReadKey();
        }
        static object obj = new object();
        public static void ThreadMethod()
        {
            bool flag = Monitor.TryEnter(obj, 1000);   //设置1S的超时时间,如果在1S之内没有获得同步锁,则返回false
        //上面的代码设置了锁定超时时间为1秒,也就是说,在1秒中后,
       //lockObj还未被解锁,TryEntry方法就会返回false,如果在1秒之内,lockObj被解锁,TryEntry返回true。我们可以使用这种方法来避免死锁
            try
            {
                if (flag)
                {
                    for (int i = 0; i < 500; i++)
                    {
                        Console.Write(Thread.CurrentThread.Name); 
                    }
                }
            }
            catch(Exception ex)
            {

            }
            finally
            {
                if (flag)
                    Monitor.Exit(obj);
            } 
        } 

新匍京视频在线 86

 

private static object obj = new object();
        static void Main(string[] args)
        {
            Program pro1 = new Program();                    
            Program pro2 = new Program();                   
            Thread threadA = new Thread(pro1.ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "王文建";
            Thread threadB = new Thread(pro2.ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "生旭鹏";
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }
        public void ThreadMethod(object parameter)
        {
            lock (obj)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name, i);
                    Thread.Sleep(300);
                }
            }
        }
     static void Main(string[] args)
        {                
            Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadA.Name = "A";
            Thread threadB = new Thread(ThreadMethod); //执行的必须是无返回值的方法 
            threadB.Name = "B";
            threadA.Start();
            threadB.Start();
            Thread.CurrentThread.Name = "C";
            ThreadMethod();
            Console.ReadKey();
        }
        static object obj = new object();
        public static void ThreadMethod()
        {
            Monitor.Enter(obj);      //Monitor.Enter(obj)  锁定对象
            try
            {
                for (int i = 0; i < 500; i++)
                {
                    Console.Write(Thread.CurrentThread.Name); 
                }
            }
            catch(Exception ex){   }
            finally
            { 
                Monitor.Exit(obj);  //释放对象
            } 
        } 

 

  线程安全是指在当一个线程访问该类的某部数据时,举行维护,其他线程无法展开访问直到该线程读取完,其他线程才可使用。不会并发数量不相同或者数额污染。

新匍京视频在线 87

    Pulse 布告等待队列中的线程锁定目的情状的变动。

Wait(object)方法:释放对象上的锁并阻止当前线程,直到它再也赢得该锁,该线程进入等待队列。
 Pulse方法:只有锁的当下主人可以动用 Pulse 向等待对象发出信号,当前持有指定对象上的锁的线程调用此方法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被挪动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不必然是吸纳到脉冲的线程)将获取该锁。
另外

咱俩得以由此地方表中的性质获取线程的部分相关音信,下边是代码展示和出口结果:

接下来在概念一个攻击类

下一场在概念一个玩家类,攻击类

新匍京视频在线 88

   3、线程同步

新匍京视频在线 89

新匍京视频在线 90😉

    Wait(Object) 释放对象上的锁并阻止当前线程,直到它再度取得该锁。

为了阐明方面所说的,大家先是看一段代码:  

     lock(obj)

从运行结果可以观看,首先程序中有五个线程,ThreadA、ThreadB和主线程,首先主线程先阻塞,然后线程ThreadB阻塞,ThreadA先实施,执行完毕之后ThreadB接着执行,最终才是主线程执行。

  3.0 使用Lock关键字贯彻线程同步 

View Code

新匍京视频在线 91

 输输出结果: 

/// <summary>
    /// 攻击类
    /// </summary>
    internal class Play
    {
        /// <summary>
        /// 攻击者名字
        /// </summary>
        public string Name { get; set; } 
        /// <summary>
        /// 攻击力
        /// </summary>
        public int Power{ get; set; }
        /// <summary>
        /// 法术攻击
        /// </summary>
        public void magicExecute(object monster)
        {
            Monster m = monster as Monster;
            Monitor.Enter(monster);
            while (m.Blood>0)
            {
                Monitor.Wait(monster);
                Console.WriteLine("当前英雄:{0},正在使用法术攻击打击怪物", this.Name);
                if(m.Blood>= Power)
                {
                    m.Blood -= Power;
                }
                else
                {
                    m.Blood = 0;
                }
                Thread.Sleep(300);
                Console.WriteLine("怪物的血量还剩下{0}", m.Blood);
                Monitor.PulseAll(monster);
            }
            Monitor.Exit(monster);
        }
        /// <summary>
        /// 物理攻击
        /// </summary>
        /// <param name="monster"></param>
        public void physicsExecute(object monster)
        {
            Monster m = monster as Monster;
            Monitor.Enter(monster);
            while (m.Blood > 0)
            {
                Monitor.PulseAll(monster);
                if (Monitor.Wait(monster, 1000))     //非常关键的一句代码
                {
                    Console.WriteLine("当前英雄:{0},正在使用物理攻击打击怪物", this.Name);
                    if (m.Blood >= Power)
                    {
                        m.Blood -= Power;
                    }
                    else
                    {
                        m.Blood = 0;
                    }
                    Thread.Sleep(300);
                    Console.WriteLine("怪物的血量还剩下{0}", m.Blood);
                }
            }
            Monitor.Exit(monster);
        }
    }

View Code

  先是种状态:

 

线程是依托在经过上的,进程都终止了,线程也就烟消云散了!

    static void Main(string[] args)
        {
            Thread[] thread = new Thread[3];
            for (int i = 0; i < 3; i++)
            {
                thread[i] = new Thread(ThreadMethod1);
                thread[i].Name = i.ToString();
            }
            for (int i = 0; i < 3; i++)
            {
                thread[i].Start();
            }
            Console.ReadKey(); 
        } 

        public static void ThreadMethod1(object val)
        {
            mutet.WaitOne();    //获取锁
            for (int i = 0; i < 500; i++)
            {
                Console.Write(Thread.CurrentThread.Name); 
            } 
            mutet.ReleaseMutex();  //释放锁
        }

新匍京视频在线 92

  2.2.1 Abort()方法

新匍京视频在线 93

    PulseAll 布告所有的等候线程对象情状的改动。

 

推行代码:

  2.2.3 Sleep()方法 

    
 Join方法紧如若用来阻塞调用线程,直到某个线程终止或透过了指定时间结束。官方的表达相比较单调,通俗的说就是创建一个子线程,给它加了这么些法子,另外线程就会搁浅实施,直到这些线程执行完截止才去履行(包括主线程)。她的法门表明如下:

    TryEnter(Object,
Boolean)
 尝试得到指定对象上的排他锁,并自动安装一个值,提示是否收获了该锁。

新匍京视频在线 94😉

  3.0 使用Mutex类实现线程同步

  
   Abort方法可以经过跑出ThreadAbortException非常中止线程,而采纳ResetAbort方法可以撤废中止线程的操作,上边通过代码演示使用 ResetAbort方法。

1、概念

public class Singleton
{
       private static Singleton instance;
       private static object obj=new object(); 
       private Singleton()        //私有化构造函数
       {

       } 
       public static Singleton GetInstance()
       {
               if(instance==null)
               {
                      lock(obj)      //通过Lock关键字实现同步
                      {
                             if(instance==null)
                             {
                                     instance=new Singleton();
                             }
                      }
               }
               return instance;
       }
}

新匍京视频在线 95

线程和此外常见的类一样,有着广大性能和形式,参考下表:

public class Singleton
    {
        private static Singleton instance; 
        private Singleton()   //私有函数,防止实例
        {

        } 
        public static Singleton GetInstance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
public class Singleton
    {
        private static Singleton instance; 
        private Singleton()   //私有函数,防止实例
        {

        } 
        public static Singleton GetInstance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }

 

           Monitor的常用属性和办法:

咱俩得以因此下边表中的属性获取线程的片段有关音讯,下边是代码显示和出口结果:

 

TryEnter(Object)TryEnter() 方法在品味拿到一个对象上的显式锁方面和
Enter()方法类似。但是,它不像Enter()方法这样会堵塞执行。如若线程成功进去关键区域那么TryEnter()方法会再次来到true. 和总括拿走指定对象的排他锁。看下边代码演示:

 首先我们定义一个怪物类,被攻击类,

    Enter(Object) 在指定对象上取得排他锁。

新匍京视频在线 96

        public static void Sleep(TimeSpan timeout);          //时间段
        public static void Sleep(int millisecondsTimeout);   //毫秒数

俺们会发觉,线程又不曾实现协同了!lock(this)对于这种情景是很是的!所以需要我们对代码举办修改!修改后的代码如下: 

新匍京视频在线 97

 

           Monitor的常用属性和章程:

多线程的亮点 

新匍京视频在线 98

http://www.cnblogs.com/JeffreyZhao/archive/2009/07/22/thread-pool-1-the-goal-and-the-clr-thread-pool.html

新匍京视频在线 99

    这两者的界别就是:应用程序必须运行完所有的前台线程才可以退出;而对此后台线程,应用程序则可以不考虑其是否业已运行完毕而一向退出,所有的后台线程在应用程序退出时都会自动终止。一般后台线程用于拍卖时间较短的天职,如在一个Web服务器中可以选取后台线程来处理客户端发过来的伏乞音信。而前台线程一般用来拍卖需要长日子等待的任务,如在Web服务器中的监听客户端请求的顺序。

2.1 线程的有关属性

实践结果:

新匍京视频在线 100

static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            threadA.Name = "小A";
            Thread threadB = new Thread(ThreadMethod);     //执行的必须是无返回值的方法  
            threadB.Name = "小B";
            threadA.Start();
       //threadA.Join();      
            threadB.Start();
       //threadB.Join();

            for (int i = 0; i < 10; i++)
            { 
                Console.WriteLine("我是:主线程,我循环{1}次", Thread.CurrentThread.Name, i);
                Thread.Sleep(300);          //休眠300毫秒                                                
            }
            Console.ReadKey();
        } 
        public static void ThreadMethod(object parameter)  
        { 
            for (int i = 0; i < 10; i++)
            { 
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
                Thread.Sleep(300);         //休眠300毫秒              
            }
        }

新匍京视频在线 101

 

 

  1. thread_first首先取得同步对象的锁,当执行到 Monitor.Wait(monster);时,thread_first线程释放自己对共同对象的锁,流放自己到等候队列,直到自己再也得到锁,否则一向不通。
  2. 而thread_second线程一最先就竞争同步锁所以处于就绪队列中,这时候thread_second直接从稳妥队列出来得到了monster对象锁,起首实践到Monitor.PulseAll(monster)时,发送了个Pulse信号。
  3. 这时候thread_first接收到信号进入到妥善状态。然后thread_second继续往下实施到
    Monitor.Wait(monster, 1000)时,这是一句万分关键的代码,thread_second将协调放逐到等候队列并释放自身对同步锁的独占,该等待安装了1S的超时值,当B线程在1S之内没有重新获拿到锁自动添加到就绪队列。
  4. 这时thread_first从Monitor.Wait(monster)的隔阂截止,重回true。开端执行、打印。执行下一行的Monitor.Pulse(monster),这时候thread_second如果1S的日子还没过,thread_second接收到信号,于是将协调添加到就绪队列。
  5. thread_first的联手代码块截至未来,thread_second再一次赢得执行权, Monitor.Wait(m_smplQueue,
    1000)再次回到true,于是继续从该代码处往下举行、打印。当再一次实施到Monitor.Wait(monster,
    1000),又起来了步骤3。
  6. 逐一循环。。。。
public class Singleton
{
       private static Singleton instance;
       private static object obj=new object(); 
       private Singleton()        //私有化构造函数
       {

       } 
       public static Singleton GetInstance()
       {
               if(instance==null)
               {
                      lock(obj)      //通过Lock关键字实现同步
                      {
                             if(instance==null)
                             {
                                     instance=new Singleton();
                             }
                      }
               }
               return instance;
       }
}

 

新匍京视频在线 102

View Code

       static void Main(string[] args)
        {
            Thread threadA = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            threadA.Name = "小A";
            threadA.Start();
            Console.ReadKey();
        } 
        public static void ThreadMethod(object parameter)  
        { 
            for (int i = 0; i < 10; i++)
            { 
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
                Thread.Sleep(300);         //休眠300毫秒              
            }
        }

 

新匍京视频在线 103

     
 单例模式就是保证在全方位应用程序的生命周期中,在任几时刻,被指定的类唯有一个实例,并为客户程序提供一个取得该实例的大局访问点。但下面代码有一个精通的题材,这就是假使六个线程同时去得到那个目标实例,这。。。。。。。。

多线程的亮点 

1
2
1、 多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程
2、 提高了CPU的利用率,就可以直接提高程序的整体执行速度

    这三头的区别就是:应用程序必须运行完所有的前台线程才方可退出;而对于后台线程,应用程序则足以不考虑其是否业已运行完毕而直白退出,所有的后台线程在应用程序退出时都会活动终止。一般后台线程用于拍卖时间较短的职责,如在一个Web服务器中得以行使后台线程来拍卖客户端发过来的伸手音信。而前台线程一般用于拍卖需要长日子等待的职责,如在Web服务器中的监听客户端请求的主次。

     Abort()方法用来终止线程,调用此措施强制截止正在推行的线程,它会抛出一个ThreadAbortException分外从而导致目的线程的截至。下边代码演示:

新匍京视频在线 104

 

       执行下边的代码。窗口并没有顿时执行
ThreadMethod方法输出循环数字,而是等待了三分钟之后才输出,因为线程起初施行的时候实施了Suspend()方法挂起。然后主线程休眠了3分钟将来又经过Resume()方法復苏了线程threadA。

一贯上代码来看功能:

   
 
C#中的线程分为前台线程和后台线程,线程创建时不做设置默认是前台线程。即线程属性IsBackground=false。

 Monitor.Wait和Monitor()Pause()

看实践结果:

新匍京视频在线 105😉

新匍京视频在线 106

现行我们把代码中的  ThreadA.join()方法注释撤销,在探访执行的效率呢!

 

新匍京视频在线 107新匍京视频在线 108

1
2
1、 多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程
2、 提高了CPU的利用率,就可以直接提高程序的整体执行速度
static void Main(string[] args)     
        {
            Thread thread = new Thread(ThreadMethod);     //执行的必须是无返回值的方法 
            thread.Name = "小A";
            thread.Start();  
            Console.ReadKey();
        }

        public static void ThreadMethod(object parameter)  
        {
            Console.WriteLine("我是:{0},我要终止了", Thread.CurrentThread.Name);
            //开始终止线程
            Thread.CurrentThread.Abort();
            //下面的代码不会执行
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread.Name,i);
            }
        }

总结:

    Wait(Object)
释放对象上的锁并阻止当前线程,直到它再一次拿到该锁。

  第一创设多个线程,三个线程执行同一个措施,参考下边的代码:

首先应用new
Thread()创造出新的线程,然后调用Start方法使得线程进入就绪状态,得到系统资源后就实施,在推行过程中或许有等待、休眠、死亡和隔阂四种情景。正常履行完毕时间片后再次来到到就绪状态。如果调用Suspend方法会跻身等待境况,调用Sleep或者境遇进程同步使用的锁机制而休眠等待。具体过程如下图所示:

新匍京视频在线 109

 public virtual bool WaitOne()  阻止当前线程,直到近期 System.Threading.WaitHandle
收到信号获取互斥锁。

新匍京视频在线 110

因为线程之间的推行是擅自的,所有执行结果和大家想象的相同,杂乱无章!不过表达她们是还要推行的。如下图

经过地方的履行结果,可以很精通的来看,五个线程是在同时履行ThreadMethod这多少个法子,这显著不合乎我们线程同步的渴求。我们对代码举行修改如下:

  第一种情景:

    1.单个任务处理的时光相比短 
    2.索要处理的天职的数目大 

   第三种处境:thread_second首先拿到同步锁对象,首先实施到Monitor.PulseAll(monster),因为程序中从不索要等待信号进入就绪状态的线程,所以这一句代码没有意义,当执行到 Monitor.Wait(monster,
1000),自动将协调放逐到等候队列并在这里阻塞,1S 时间之后thread_second自动添加到就绪队列,线程thread_first得到monster对象锁,执行到Monitor.Wait(monster);时发出短路释放同步对象锁,线程thread_second执行,执行Monitor.PulseAll(monster)时通知thread_first。于是又起来率先种境况…

   线程有可能和另外线程共享一些资源,比如,内存,文件,数据库等。当六个线程同时读写同一份共享资源的时候,可能会引起顶牛。这时候,我们需要引入线程“同步”机制,即诸君线程之间要有个先来后到,不可能一窝蜂挤上去抢作一团。线程同步的真实意思和字面意思恰好相反。线程同步的诚实意思,其实是“排队”:多少个线程之间要排队,一个一个对共享资源实行操作,而不是还要拓展操作。

  首先创设五个线程,四个线程执行同一个艺术,参考下边的代码:

实践结果:

        2.2.5 Suspent()和Resume()方法

新匍京视频在线 111

这就是说我们把代码中的
 ThreadA.join()方法和ThreadB.join()方法注释都裁撤,在看望执行的功能呢!

   
  下边介绍了介绍了平日应用的大多数的多线程的例子,但在骨子里开支中接纳的线程往往是大度的和越来越复杂的,这时,每一遍都创设线程、启动线程。从性能上来讲,这样做并不理想(因为每使用一个线程就要创制一个,需要占用系统开发);从操作上来讲,每便都要启动,相比较劳顿。为此引入的线程池的定义。

     

因为线程之间的实践是不管三七二十一的,所有执行结果和我们想像的同样,杂乱无章!可是表明他俩是同时履行的。新匍京视频在线 112

新匍京视频在线 113😉

3、保证lock的靶子在外部无法修改才有意义,即便lock的靶子在外部改变了,对任何线程就会通行,失去了lock的含义。

2、线程的基本操作

?

Enter(Object)的用法很简短,看代码 

新匍京视频在线 114😉

怎么要实现共同啊,下边的事例我们拿出名的单例格局以来呢。看代码

举行结果:和大家想象的等同,上边的巡回没有被实践

/// <summary>
    /// 怪物类
    /// </summary>
    internal class Monster
    {
        public int Blood { get; set; }
        public Monster(int blood)
        {
            this.Blood = blood;
            Console.WriteLine("我是怪物,我有{0}滴血",blood);
        }
    }

新匍京视频在线 115

线程是依托在经过上的,进程都截止了,线程也就消灭了!

  一旦在应用程序中有两个线程在运行,但一些线程比另一部分线程首要,这种场所下得以在一个经过中为不同的线程指定不同的优先级。线程的预先级能够经过Thread类Priority属性设置,Priority属性是一个ThreadPriority型枚举,列举了5个先行等级:Above诺玛l、BelowNormal、Highest、Lowest、诺玛(Norma)l。公共语言运行库默认是诺玛l类型的。见下图:

  1.减小在创制和销毁线程上所花的年月以及系统资源的开销 
 
2.如不使用线程池,有可能引致系统创建大气线程而导致消耗完系统内存以及”过度切换”。

新匍京视频在线 116

相关文章