先前也知道,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);
}
}
}