线程同步及线程用到的锁对象
如果程序涉及到多个线程协同完成某项任务,那么你将会面对线程同步的问题。.Net为这类为题提供了很好的解决方案,我们只需要书写少量的代码就能避免线程出现死锁。
线程同步
辅助类
class ThreadSync
{
public long data1;
public long data2;
public void Increase()
{
data2++;
}
}
class AlgorithmicTimer
{
public DateTime startTime { get; set; }
public DateTime endTime { get; set; }
public void Analyse()
{
Console.WriteLine(
string.Format("当前程序共运行了:{0}秒"
, (endTime - startTime).TotalSeconds));
}
}
}
调用代码
ThreadSync myThreadSync = new ThreadSync();
AlgorithmicTimer timer = new AlgorithmicTimer();
timer.startTime = DateTime.Now;
for (int i = 0; i < 100000000; i++)
{
myThreadSync.Increase();
}
Console.WriteLine(myThreadSync.data2);
timer.endTime = DateTime.Now;
timer.Analyse();
myThreadSync.data2 = 0;
timer.startTime = DateTime.Now;
Parallel.For(0, 100000000, (index) =>
{
lock (myThreadSync) //不加上Lock得到的结果不正确
{
myThreadSync.Increase();
}
});
Console.WriteLine(myThreadSync.data2);
timer.endTime = DateTime.Now;
timer.Analyse();
执行结果
100000000 当前程序共运行了:1.1740671秒 100000000 当前程序共运行了:11.4436546秒 |
PV信号量操作
//Semaphore 信号量对象,PV 操作
int threadCount = 6;
int semaphoreCount = 4;
var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
var threads = new Thread[threadCount];
for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(mysemaphore.ThreadMain);
threads[i].Start(semaphore);
}
for (int i = 0; i < threadCount; i++)
{
threads[i].Join();
}
Console.WriteLine("All threads finished!");
Mysemaphore类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace chapter20
{
class mysemaphore
{
public static void ThreadMain(object o)
{
SemaphoreSlim semaphore = o as SemaphoreSlim;
Trace.Assert(semaphore != null, "o must be a Semaphore type");
bool isCompleted = false;
while (!isCompleted)
{
if (semaphore.Wait(600))
{
try
{
Console.WriteLine("Thread {0} locks the semaphore
,Current PV:{1}"
, new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount});
Thread.Sleep(2000);
}
finally
{
semaphore.Release();
Console.WriteLine("Thread {0} release the semaphore,Current PV:{1}", new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount});
isCompleted = true;
}
}
else
{
Console.WriteLine("Timeout for thread {0},wait again", Thread.CurrentThread.ManagedThreadId);
}
}
}
}
}
执行结果:
Thread 9 locks the semaphore,Current PV:3 Thread 10 locks the semaphore,Current PV:2 Thread 11 locks the semaphore,Current PV:1 Thread 12 locks the semaphore,Current PV:0 Timeout for thread 13,wait again Timeout for thread 14,wait again Timeout for thread 13,wait again Timeout for thread 14,wait again Thread 9 release the semaphore,Current PV:1 Thread 13 locks the semaphore,Current PV:0 Thread 11 release the semaphore,Current PV:2 Timeout for thread 14,wait again Thread 10 release the semaphore,Current PV:1 Thread 14 locks the semaphore,Current PV:2 Thread 12 release the semaphore,Current PV:3 Thread 13 release the semaphore,Current PV:3 Thread 14 release the semaphore,Current PV:4 All threads finished!
|
Event类
解决资源分配问题,当程序释放资源时改变该事件的状态。通知其他程序它释放了资源。
辅助类
class Calculator
{
private ManualResetEventSlim mEvent;
public int Result { get; private set; }
public Calculator(ManualResetEventSlim ev)
{
this.mEvent = ev;
}
public void Calculation(object obj)
{
Tuple<int, int> data = obj as Tuple<int, int>;
Console.WriteLine("Task {0} starts calculation"
, Task.CurrentId);
Thread.Sleep(new Random().Next(3000));
Result = data.Item1 + data.Item2;
Console.WriteLine("Task {0} is ready", Task.CurrentId);
mEvent.Set();
}
}
调用代码:
//Event 类
int taskCount = 4;
var mEvents = new ManualResetEventSlim[taskCount];
var waitHandles = new WaitHandle[taskCount];
var calcs = new Calculator[taskCount];
TaskFactory taskFactory = new TaskFactory();
for (int i = 0; i < taskCount; i++)
{
mEvents[i] = new ManualResetEventSlim(false);
waitHandles[i] = mEvents[i].WaitHandle;
calcs[i] = new Calculator(mEvents[i]);
taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3));
}
for (int i = 0; i < taskCount; i++)
{
int index = WaitHandle.WaitAny(waitHandles);
if (index == WaitHandle.WaitTimeout)
{
Console.WriteLine("Timeout!!");
}
else
{
mEvents[index].Reset();
Console.WriteLine("finished task for {0},result:{1}", index, calcs[index].Result);
}
}
执行结果:
Task 1 starts calculation Task 3 starts calculation Task 2 starts calculation Task 4 starts calculation Task 2 is ready Task 3 is ready Task 4 is ready finished task for 1,result:6 finished task for 2,result:8 finished task for 3,result:10 Task 1 is ready finished task for 0,result:4
|
ReadWriterLockSlim(同步资源的读写)
呵呵,额对这个东西的产生表示很无解。
class MyReadWriterLockSlim
{
private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };
private static ReaderWriterLockSlim rwl = new
ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public static void ReaderMethod(object reader)
{
try
{
rwl.EnterReadLock();
for (int i = 0; i < items.Count; i++)
{
Console.WriteLine("reader {0}, loop: {1}, item: {2}",
reader, i, items[i]);
Thread.Sleep(40);
}
}
finally
{
rwl.ExitReadLock();
}
}
public static void WriterMethod(object writer)
{
try
{
while (!rwl.TryEnterWriteLock(50))
{
Console.WriteLine("Writer {0} waiting for the write lock",
writer);
Console.WriteLine("current reader count: {0}",
rwl.CurrentReadCount);
}
Console.WriteLine("Writer {0} acquired the lock", writer);
for (int i = 0; i < items.Count; i++)
{
items[i]++;
Thread.Sleep(50);
}
Console.WriteLine("Writer {0} finished", writer);
}
finally
{
rwl.ExitWriteLock();
}
}
public static void Go()
{
var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
var tasks = new Task[6];
tasks[0] = taskFactory.StartNew(WriterMethod, 1);
tasks[1] = taskFactory.StartNew(ReaderMethod, 1);
tasks[2] = taskFactory.StartNew(ReaderMethod, 2);
tasks[3] = taskFactory.StartNew(WriterMethod, 2);
tasks[4] = taskFactory.StartNew(ReaderMethod, 3);
tasks[5] = taskFactory.StartNew(ReaderMethod, 4);
for (int i = 0; i < 6; i++)
{
tasks[i].Wait();
}
}
}
执行结果:
reader 1, loop: 0, item: 0 reader 1, loop: 1, item: 1 reader 3, loop: 0, item: 0 Writer 1 waiting for the write lock current reader count: 3 reader 4, loop: 0, item: 0 Writer 2 waiting for the write lock reader 1, loop: 2, item: 2 reader 3, loop: 1, item: 1 current reader count: 3 reader 4, loop: 1, item: 1 reader 3, loop: 2, item: 2 reader 1, loop: 3, item: 3 reader 4, loop: 2, item: 2 Writer 1 waiting for the write lock reader 3, loop: 3, item: 3 current reader count: 3 Writer 2 waiting for the write lock reader 1, loop: 4, item: 4 reader 3, loop: 4, item: 4 reader 4, loop: 3, item: 3 current reader count: 3 Writer 1 waiting for the write lock current reader count: 3 reader 3, loop: 5, item: 5 reader 1, loop: 5, item: 5 reader 4, loop: 4, item: 4 reader 4, loop: 5, item: 5 Writer 2 waiting for the write lock Writer 1 waiting for the write lock current reader count: 1 reader 2, loop: 0, item: 0 current reader count: 1 reader 2, loop: 1, item: 1 Writer 2 waiting for the write lock Writer 1 waiting for the write lock reader 2, loop: 2, item: 2 current reader count: 1 current reader count: 1 reader 2, loop: 3, item: 3 Writer 1 waiting for the write lock Writer 2 waiting for the write lock reader 2, loop: 4, item: 4 current reader count: 1 current reader count: 1 reader 2, loop: 5, item: 5 Writer 2 waiting for the write lock Writer 1 waiting for the write lock current reader count: 0 current reader count: 0 Writer 1 acquired the lock Writer 2 waiting for the write lock current reader count: 0 Writer 2 waiting for the write lock current reader count: 0 Writer 2 waiting for the write lock current reader count: 0 Writer 1 finished Writer 2 acquired the lock Writer 2 finished
|