线程同步
线程同步的方式有多种,这里只写两种可能常用的。
线程锁主要用于多线程对同一资源进行访问时产生的问题。
1.lock 很简单。
2.montor 获取资源使用monitor.Enter(),释放资源 Monitor.Exit();两者合起来相当于lock。
3、以上两种当多线程对统一资源进行访问时同时只能有一个线程访问,会造成其他线程阻塞的情况,例如多个线程同时读取一个资源时就会产生这种情况,线程阻塞又浪费资源,不是必要的,希望多线程能够同时读取同一的资源,可以使用另一种线程同步的方式:ReaderWriterLock
使用方:写入时使用 ReaderWriterLock的AcquireWriterLock(int time)方法 time为超时时间 释放写入锁为 ReleaseWriterLock() 方法。
读取时使用: ReaderWriterLock的AcquireReaderLock(int time) 方法 其中time为超时时间 毫秒 释放读取锁为:ReleaseReaderLock()方法。
总结:其他还有线程同步的方式,我不常用不在这里写了 ,线程同步是一项十分耗费资源和性能的工作,对性能的伤害比较大,本机测试大致使用线程同步耗费的时间是不使用线程同步耗费时间的8倍左右。所以线程同步一定要慎用,如果程序中必须使用线程同步的话枷锁的代码越少越好,尽量使枷锁的时间缩短。
举例说明:
monitor的方式:
using System; using System.Threading; namespace MonitorSample { class Program { static void Main(string[] args) { for (int i = 0; i < 10; i++) { Thread test = new Thread(Add); test.Start(); } Console.Read(); } // 共享资源 public static int number = 0; public static void Add() { Thread.Sleep(1000); //获得排他锁 Monitor.Enter(number); Console.WriteLine("the current value of number is:{0}", number++); // 释放指定对象上的排他锁。 Monitor.Exit(number); } } }
ReaderWriterLock的方式:
using System; using System.Collections.Generic; using System.Threading; namespace ReaderWriterLockSample { class Program { public static List<int> lists = new List<int>(); // 创建一个对象 public static ReaderWriterLock readerwritelock = new ReaderWriterLock(); static void Main(string[] args) { //创建一个线程读取数据 Thread t1 = new Thread(Write); t1.Start(); // 创建10个线程读取数据 for (int i = 0; i < 10; i++) { Thread t = new Thread(Read); t.Start(); } Console.Read(); } // 写入方法 public static void Write() { // 获取写入锁,以10毫秒为超时。 readerwritelock.AcquireWriterLock(10); Random ran = new Random(); int count = ran.Next(1, 10); lists.Add(count); Console.WriteLine("Write the data is:" + count); // 释放写入锁 readerwritelock.ReleaseWriterLock(); } // 读取方法 public static void Read() { // 获取读取锁 readerwritelock.AcquireReaderLock(10); //Lam表达式展示 lists.ForEach(r=>{Console.WriteLine(r.ToSting());}); // 释放读取锁 readerwritelock.ReleaseReaderLock(); } } }