要避免同步问题,最好不要在线程之间使用共享数据。如果仍需要共享数据。就需要使用同步技术。
lock语句 是简单的锁定。
InterLocked类 实现原子级的锁定。
Monitor类 优点是可以指定等待的时间参数,超过时间就不会一直等待下去。
SpinLock结构 SpinLock 减轻垃圾回收压力。尝试获取锁的线程将在重复检查的循环中等待,直至该锁变为可用为止。仅当您确定这样做可以改进应用程序的性能之后才能使用
WaitHandle类 抽象基类,用于等待信号的设置。
Mutex类 可用于指定程序单一执行。
Semaphore类 旗语类。用于处理有多个资源可供有限线程访问的情况。如三个USB口只能同时允许三个线程访问。
以下三类见下一篇
Event 类 是发出信号的类。与WaitHandle配对使用。
Barrier类
ReaderWriteLockSlim类
lock语句:
是简单的锁定。为多个线程提供自己的关键字。这个锁定的类一定要是引用类型,才能被锁定。
锁定实例类:
LockStatus lk=new LockStatus();
lock(lk)
{
//dosomething
}
public class LockStatus
{ }
锁定静态类:
class Program
{
static void Main(string[] args)
{
lock (typeof(LockStatus))
{
//dosomething
}
// Console.WriteLine("class is ready");
}
}
public static class LockStatus
{ }
InterLocked类:实现原子级的锁定。即简单的i++,i--。这个锁定只针对这样简单的锁定,但访问的速度较快。
Monitor类 优点是可以指定等待的时间参数,超过时间就不会一直等待下去。
class Program
{
static object obj = new object();
static void Main(string[] args)
{
lock (obj)
{
System.Threading.Tasks.Task.Run(() => LockStatus(obj));
System.Threading.Thread.Sleep(600);
}
Console.ReadKey();
}
public static void LockStatus(object obj)
{
bool lockTaken = false;
System.Threading.Monitor.TryEnter(obj, 500, ref lockTaken);
if (lockTaken)
{
try
{
Console.WriteLine("dosomthing");
}
finally
{
System.Threading.Monitor.Exit(obj);
}
}
else
{
Console.WriteLine("don't get the lock;");
}
}
}
SpinLock结构 SpinLock 减轻垃圾回收压力。尝试获取锁的线程将在重复检查的循环中等待,直至该锁变为可用为止。仅当您确定这样做可以改进应用程序的性能之后才能使用.下面的示例来自MSDN
static void SpinLockSample1() { SpinLock sl = new SpinLock(); StringBuilder sb = new StringBuilder(); // Action taken by each parallel job. // Append to the StringBuilder 10000 times, protecting // access to sb with a SpinLock. Action action = () => { bool gotLock = false; for (int i = 0; i < 10000; i++) { gotLock = false; try { sl.Enter(ref gotLock); sb.Append((i % 10).ToString()); } finally { // Only give up the lock if you actually acquired it if (gotLock) sl.Exit(); } } }; // Invoke 3 concurrent instances of the action above Parallel.Invoke(action, action, action); // Check/Show the results Console.WriteLine("sb.Length = {0} (should be 30000)", sb.Length); Console.WriteLine("number of occurrences of '5' in sb: {0} (should be 3000)", sb.ToString().Where(c => (c == '5')).Count()); }
WaitHandle类
class Program
{
delegate int delegateTask();
static void Main(string[] args)
{
delegateTask d1 = threadRun;
var result = d1.BeginInvoke(null, null);
while (true)
{
if(result.AsyncWaitHandle.WaitOne(100,false))
{
break;
}
}
int a = d1.EndInvoke(result);
Console.WriteLine("结果是{0}", a);
Console.ReadKey();
}
private static int threadRun()
{
Thread.Sleep(500);
return 12;
}
Mutex类 可用于指定程序单一执行。
bool createNew;
var mutex = new System.Threading.Mutex(false, "singletonWinAppMutex",out createNew);
if (!createNew)
{
Console.WriteLine("已经有程序在运行");
Console.ReadKey();
}
else
{
Console.WriteLine("程序正在运行");
Console.ReadKey();
}
Semaphore类
class Program
{
static void Main(string[] args)
{
int taskCount = 6;
int semaphoreCount = 3;
SemaphoreSlim semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
Task[] tasks=new Task[taskCount];
for (int i = 0; i < taskCount; i++)
{
tasks[i] = Task.Run(() => TaskMain(semaphore));
}
Task.WaitAll(tasks);
Console.WriteLine("Task is Completed");
Console.ReadKey();
}
private static void TaskMain(SemaphoreSlim semaphore)
{
bool isCompleted=false;
while (!isCompleted)
{
if(semaphore.Wait(500))
{
try
{
Console.WriteLine("Task {0} locked the semaphor", Task.CurrentId);
Thread.Sleep(2000);
}
finally
{
Console.WriteLine("Task {0} releases the semaphor", Task.CurrentId);
semaphore.Release();
isCompleted = true;
}
}
else
{
Console.WriteLine("Task {0} not locked the semaphor,await again", Task.CurrentId);
}
}
}
}