01.Lock01L解决了多个线程对同一资源的共享使用问题,确保一个线程在lock到资源后,另外需要资源的线程只能处于等待状态。
lock并不能解决线程间顺序执行的问题

class Program
{
static void Main(string[] args)
{
MultiThreadSynergicWithLock();
Console.ReadKey();
}

/// <summary>
/// 多线程协作lock 解决多线程对单一资源的共享
/// </summary>
private static void MultiThreadSynergicWithLock()
{
int[] array=new int[3];
Thread producer=new Thread(() =>
{
int count = 0;
Random random=new Random();
while (true)
{
if (count==10)
{
break;
}

lock (array)
{
array[0] = random.Next(10);
array[1] = random.Next(10);
array[2] = random.Next(10);
count++;
Thread.Sleep(500);
Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
}
}


});

producer.Name = "producer";

Thread customer=new Thread(() =>
{
int count = 0;
while (true)
{
if (count == 10)
{
break;
}

lock (array)
{
array[0] = 0;
array[1] = 0;
array[2] = 0;
count++;
Thread.Sleep(500);
Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
}
}
});
customer.Name = "customer";
producer.Start();
customer.Start();

}

}

4.线程_互斥


02.

lock实际上是Monitor操作的简化版本

4.线程_c#_02

static void Main(string[] args)
{
MultiThreadSynergicWithLock();
Console.ReadKey();
}
private static void MultiThreadSynergicWithLock()
{
int[] array=new int[3];
Thread producer=new Thread(() =>
{
int count = 0;
Random random = new Random();
while (true)
{
if (count==10)
{
break;
}
//The object on which to acquire the monitor lock.
Monitor.Enter(array);
Thread.Sleep(300);
array[0] = random.Next(10);
array[1] = random.Next(10);
array[2] = random.Next(10);
count++;
Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
Monitor.Pulse(array);
Monitor.Wait(array);

}
//The object on which to release the lock
Monitor.Exit(array);
});
producer.Name = "producer";

Thread customer = new Thread(() =>
{
int count = 0;
Random random = new Random();
while (true)
{
if (count == 10)
{
break;
}
//The object on which to acquire the monitor lock.
Monitor.Enter(array);
Thread.Sleep(300);
array[0] = 0;
array[1] = 0;
array[2] = 0;
count++;
Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2]));
Monitor.Pulse(array);
Monitor.Wait(array);

}
//The object on which to release the lock
Monitor.Exit(array);
});
customer.Name = "customer";
producer.Start();
customer.Start();
}

03.Mutex互斥锁

它是一个互斥的对象,同一时间只有一个线程可以拥有它,该类还可用于进程间同步的同步基元。
如果当前有一个线程拥有它,在没有释放之前,其它线程是没有权利拥有它的。我们可以把Mutex看作洗手间,上厕所的人看作线程;上厕所的人先进洗手间,拥有使用权,上完厕所之后出来,把洗手间释放,其他人才可以使用。
线程使用Mutex.WaitOne()方法等待C# Mutex对象被释放,如果它等待的C# Mutex对象被释放了,它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象,而在此期间,其他想要获取这个C# Mutex对象的线程都只有等待。

class Program
{
static void Main(string[] args)
{
MultiThreadSynergicWithMutex();
Console.ReadKey();
}

private static void MultiThreadSynergicWithMutex()
{
//initiallyOwned表示创建mutex的线程是否拥有该互斥体
//true表示创建线程拥有互斥锁,只有在创建线程中调用ReleaseMutex释放后,其他等待线程才能参与抢夺互斥体的活动
//false表示互斥锁体于与空闲状态,其他等待互斥锁的线程立即参与到抢夺互斥锁的活动中去

//在这个程序中创建mutex时使用true参数,故在启动其他线程后必须执行mutex.ReleaseMutex()
//如果不释放mutex,则其他线程将一直等待下去
Mutex mutex =new Mutex(true);

Thread thread1=new Thread(() =>
{
//mutex.WaitOne()与mutex.ReleaseMutex()要像 { } 一样配对使用
//否则将出现 "由于出现被放弃的mutex 等待过程结束" 的异常

//程使用Mutex.WaitOne()方法等待C# Mutex对象被释放,如果它等待的C# Mutex对象被释放了
//它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象
//而在此期间,其他想要获取这个C# Mutex 对象的线程都只有等待。
mutex.WaitOne();
for (int i = 0; i < 5; i++)
{
Thread.Sleep(400);
Console.WriteLine($"{Thread.CurrentThread.Name}:{i}");
}
mutex.ReleaseMutex();
})
{
Name = "thread1",
};


Thread thread2=new Thread(() =>
{
mutex.WaitOne();
for (int i = 0; i < 5; i++)
{
Thread.Sleep(400);
Console.WriteLine($"{Thread.CurrentThread.Name}:{i}");
}
mutex.ReleaseMutex();
})
{
Name = "thread2",
};
thread1.Start();
thread2.Start();

//mutex.WaitOne()与mutex.ReleaseMutex()要像 { } 一样配对使用
//否则将出现 "由于出现被放弃的mutex 等待过程结束" 的异常
mutex.ReleaseMutex();
}

}

4.线程_互斥锁_03


04.

class Program
{
static void Main(string[] args)
{
MultiThreadSynergicWithManualResetEvent();
Console.ReadKey();
}

private static void MultiThreadSynergicWithManualResetEvent()
{
//创建一个手动重置事件。initialState参数值为false,表示创建后是否自动发出重置事件通知,false不自动发出。
ManualResetEvent mre =new ManualResetEvent(false);
Thread thread1=new Thread(() =>
{
//线程内部mre.WaitOne(),表示线程需要等待mre通知的到来后才能继续执行,线程现在处于等待状态。
mre.WaitOne();
//线程内部mre.WaitOne()后跟mre.Reset(),表示线程得到mre通知后,调用Reset终止通知的向下传递
//哪个线程先执行mre.Reset(),它就独占该通知。
mre.Reset();
Console.WriteLine("thread1 work");
//在线程启动后执行mre.Set(),表示向需要通知事件的线程发出mre通知。
//线程内部mre.Set(),线程执行完必要功能后,再次启动通知并向下传递
mre.Set();
Thread.Sleep(2000);
});
thread1.Start();
Thread thread2 = new Thread(() =>
{
mre.WaitOne();
Console.WriteLine("thread2 work");
Thread.Sleep(2000);
});
thread2.Start();
mre.Set();

}
}