Monitor类与Lock语句相比,Monitor类的主要优点是:可以添加一个等待被锁定的超时值。
缺点:开销非常大
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
ShareClass sc = new ShareClass();
Job j=new Job (sc);
Task[] ts=new Task[20];
for (int i = 0; i < 20; i++)
{
ts[i] = new Task(j.TheDoJob2);
ts[i].Start();
}
for (int i = 0; i < 20; i++)
{
ts[i].Wait();
}
Console.WriteLine(sc.state);
Console.ReadKey();
}
}
class ShareClass
{
public int state { get; set; }
}
class Job
{
ShareClass sc { get; set; }
private object obj = new object();
public Job(ShareClass s)
{
sc = s;
}
//==========普通的Monitor类
public void TheDoJob()
{
//锁定
Monitor.Enter(obj);
try
{
for (int i = 0; i < 10000; i++)
{
sc.state++;
}
}
catch { }
finally
{
//如果抛出异常也会就出锁
//释放锁
Monitor.Exit(obj);
}
}
//===========给Monitor类设置超时时间
public void TheDoJob2()
{
bool yesno=false;
//锁定
Monitor.TryEnter(obj, 100, ref yesno);
if (yesno)
{
for (int i = 0; i < 10000; i++)
{
sc.state++;
}
Console.WriteLine("yes");
//释放锁
Monitor.Exit(obj);
}
else
{
//如果超时会执行下面代码
Console.WriteLine("no");
}
}
}
}
TheDoJob()
TheDoJob2()
=================================SpinLock(自旋锁)
如果基于对象的的锁定对象(Monitor)的系统开销由于垃圾回收而过高,就可以使用SpinLock结构。如果有大量的锁定,且锁定的时间是非常短,自旋锁就很有用。
*注意:
传送SpinLock实例时要小心。因为SpinLock定义为结构,把一个变量赋予另一个变量会创建副本。总是通过引用传送SpinLock实例。
例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
ShareClass sc = new ShareClass();
Job j = new Job(sc);
int sum = 20;
Task[] t = new Task[sum];
//开启20个任务
for (int i = 0; i < sum; i++)
{
t[i] = new Task(j.JobStart);
t[i].Start();
}
//等待20个任务全部结束
for (int i = 0; i < sum; i++)
{
t[i].Wait();
}
Console.WriteLine(sc.State);
Console.ReadKey();
}
}
//共享类
class ShareClass
{
public int State { get; set; }
}
class Job
{
//声明一个自旋锁,自旋锁是一个结构(不能为属性)
private SpinLock sl;
//共享类
private ShareClass sc;
public Job(ShareClass _sc)
{
this.sc = _sc;
this.sl = new SpinLock();
}
public void JobStart()
{
//并行循环
Parallel.For(0, 10000, i =>
{
bool spinToken = false;
sl.Enter(ref spinToken);//锁定
try
{
sc.State++;
}
finally
{
if (spinToken)
sl.Exit();//释放锁
}
});
}
}
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。