若是你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。若是每次运行结果和单线程运行的结果是同样的,并且其余的变量的值也和预期的是同样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来讲是原子操做或者多个线程之间的切换不会致使该接口的执行结果存在二义性,也就是说咱们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引发的。
若每一个线程中对全局变量、静态变量只有读操做,而无写操做,通常来讲,这个全局变量是线程安全的;如有多个线程同时对一个变量执行读写操做,通常都须要考虑线程同步,不然就可能影响线程安全。
lock的目的是防止多线程执行的时候出现并发操做问题,加上lock的引用类型的对象,在其锁定的区域内,在一个时刻只容许一个线程操做。
lock只能锁定一个引用类型变量,也就是锁定一个地址安全
class Program { static void Main(string[] args) { threda t=new threda(); threda.obj.i = 10; Thread th1 = new Thread(new ThreadStart(t.hhh)); th1.Name = "th1"; th1.Start(); Thread th2 = new Thread(new ThreadStart(t.hhh)); th2.Name = "th2"; th2.Start(); } } class threda { public static sss obj = new sss(); public void hhh() { lock (obj) { for (int i = 0; i < 7; i++) { Thread.Sleep(500); if (obj.i >0) { obj.i--; Console.WriteLine("当前线程名:"+Thread.CurrentThread.Name+", obj.i= " + obj.i); } } } } } class sss { public int i ; }
加锁和不加锁运行的结果有区别 :
加锁后:i的值会一个个递减,不会出现跳跃,不会出现重复输出,一直到0值;
不加锁:i的值输出会出现跳跃,不连续递减,可能还会出现-1值输出;
缘由:加锁后,一个时刻只能有一个线程执行被锁区域的代码,两个线程都是有前后顺序执行的,因此不会出现间断输出。多线程