c# ReaderWriterLock类

先前也知道,Monitor实现的是在读写两种情况的临界区中只可以让一个线程访问,那么如果业务中存在”读取密集型“操作,就

好比数据库一样,读取的操作永远比写入的操作多。针对这种情况,我们使用Monitor的话很吃亏,不过没关系,ReadWriterLock

就很牛X,因为实现了”写入串行“,”读取并行“。

ReaderWriteLock中主要用3组方法:

<1> AcquireWriterLock: 获取写入锁。

ReleaseWriterLock:释放写入锁。

<2> AcquireReaderLock: 获取读锁。

ReleaseReaderLock:释放读锁。

<3> UpgradeToWriterLock:将读锁转为写锁。

DowngradeFromWriterLock:将写锁还原为读锁。


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication3 { class Program { static List<int> list = new List<int>(); static ReaderWriterLock rw = new System.Threading.ReaderWriterLock(); static void Main(string[] args) { Thread t1 = new Thread(AutoAddFunc); Thread t2 = new Thread(AutoReadFunc); t1.Start(); t2.Start(); Console.Read(); } public static void AutoAddFunc() { //3000ms插入一次 Timer timer1 = new Timer(new TimerCallback(Add), null, 0, 3000); } public static void AutoReadFunc() { //1000ms自动读取一次 Timer timer1 = new Timer(new TimerCallback(Read), null, 0, 1000); Timer timer2 = new Timer(new TimerCallback(Read), null, 0, 1000); Timer timer3 = new Timer(new TimerCallback(Read), null, 0, 1000); } public static void Add(object obj) { var num = new Random().Next(0, 1000); //写锁 rw.AcquireWriterLock(TimeSpan.FromSeconds(30)); list.Add(num); Console.WriteLine("我是线程{0},我插入的数据是{1}。", Thread.CurrentThread.ManagedThreadId, num); //释放锁 rw.ReleaseWriterLock(); } public static void Read(object obj) { //读锁 rw.AcquireReaderLock(TimeSpan.FromSeconds(30)); Console.WriteLine("我是线程{0},我读取的集合为:{1}", Thread.CurrentThread.ManagedThreadId, string.Join(",", list)); //释放锁 rw.ReleaseReaderLock(); } } }

  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Timers;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public List<int> list = new List<int>();
        public ReaderWriterLock rw = new ReaderWriterLock();
        private void button1_Click(object sender, EventArgs e)
        {
           //读取
            Thread t1 = new Thread(add);

            Thread t2 = new Thread(read);

            t1.Start();

            t2.Start();

            timer1.Enabled = true;
            timer2.Enabled = true;

        }


        public void add(object obj) 
        {
            //var num = new Random().Next(0, 1000);
            Thread.Sleep(30);
            Random r = new Random();




            List<int> l = new List<int>();
            for (int j = 0; j < 6; j++)
            {
                int lable = r.Next(1, 34);
                if (l.Contains(lable))
                {
                    j--;
                }
                else
                {
                    l.Add(lable);
                }
            }

            l.Sort();
            int lan = r.Next(1, 17);
            string zu = l[0].ToString() + " " + l[1].ToString() + " " + l[2].ToString() + " " + l[3].ToString() + " " + l[4].ToString() + " " + l[5].ToString() + "-" + lan;

            //写锁
            rw.AcquireWriterLock(TimeSpan.FromSeconds(30));

           

            
            listBox1.Items.Add(zu);

            //释放锁
            rw.ReleaseWriterLock();
          
        }

        public void read(object obj) 
        {
            rw.AcquireReaderLock(TimeSpan.FromSeconds(30));
            for (int i = 0; i < listBox1.Items.Count; i++) 
            {
                textBox1.Text = string.Join(",", listBox1.Items[i].ToString());
            }
                
            //释放锁
            rw.ReleaseReaderLock();
          
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            read(null);
            read(null);
            read(null);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            add(null);
        }
    }
}