C# 基础: 线程示例2-控制进度条的滚动(线程的同步)
一、 实现线程同步的方法
1.1 使用lock关键字实现线程同步
lock关键字可以用来确保代码块完成运行,不会被其他线程终断。它主要是通过在代码块运行期间为给定对象获取互斥锁来实现。
如果在静态方法中使用lock关键字,不能使用this。
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
private int num = 20; // 设置当前总票数
private void Ticket()
{
while (true)
{
lock (this)
{
if (num > 0)
{
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.Name + "-----票数" + num--);
}
}
}
}
static void Main(string[] args)
{
Program p = new Program();
Thread t1 = new Thread(new ThreadStart(p.Ticket));
t1.Name = "线程1";
Thread t2 = new Thread(new ThreadStart(p.Ticket));
t2.Name = "线程2";
Thread t3 = new Thread(new ThreadStart(p.Ticket));
t3.Name = "线程3";
Thread t4 = new Thread(new ThreadStart(p.Ticket));
t4.Name = "线程4";
t1.Start();
t2.Start();
t3.Start();
t4.Start();
}
}
}
1.2 使用Monitor类实现线程同步
Monitor类提供了同步对对象的访问机制,它通过向单个线程授予对象锁来控制对象的访问,对象锁提供限制访问代码块的能力。当一个线程拥有对象锁时,其他任何线程都不能获取该锁。
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
public static Program p = new Program();
private static int num = 30; // 设置当前总票数
private static void Ticket()
{
while (true)
{
Monitor.Enter(p);
{
if (num > 0)
{
Thread.Sleep(100);
Console.WriteLine(Thread.CurrentThread.Name + "-----票数" + num--);
}
}
Monitor.Exit(p);
}
}
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(Program.Ticket));
t1.Name = "线程1";
Thread t2 = new Thread(new ThreadStart(Program.Ticket));
t2.Name = "线程2";
Thread t3 = new Thread(new ThreadStart(Program.Ticket));
t3.Name = "线程3";
Thread t4 = new Thread(new ThreadStart(Program.Ticket));
t4.Name = "线程4";
t1.Start();
t2.Start();
t3.Start();
t4.Start();
}
}
}
1.3 使用Mutex类实现线程同步
实现线程同步还可以使用Mutex类,该类是同步基元,它只向一个线程授予对共享资源的独占访问权。Mutex本质上与Monitor类似,与监视器不同的是, Mutex类可以使跨进程的线程同步。
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
private int num = 20; // 设置当前总票数
private void Ticket()
{
while (true)
{
Mutex mutex = new Mutex(true);
mutex.WaitOne();
if (num > 0)
{
Thread.Sleep(50);
Console.WriteLine(Thread.CurrentThread.Name + "-----票数" + num--);
}
mutex.ReleaseMutex();
}
}
static void Main(string[] args)
{
Program p = new Program();
Thread t1 = new Thread(new ThreadStart(p.Ticket));
t1.Name = "线程1";
Thread t2 = new Thread(new ThreadStart(p.Ticket));
t2.Name = "线程2";
Thread t3 = new Thread(new ThreadStart(p.Ticket));
t3.Name = "线程3";
Thread t4 = new Thread(new ThreadStart(p.Ticket));
t4.Name = "线程4";
t1.Start();
t2.Start();
t3.Start();
t4.Start();
}
}
}