算法原理:每个线程进入的时候都要取得一个编号,对于不同线程编号较小的较先运行,编号相同时进程号小的先运行。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Bakery
{
class Program
{
public static int[] data = new int[100000];
public static int total = 10;
private static object ojb = new object();
static int num = 10;
static int threads=4;
static List<int> ticket = new List<int>(threads); // 保留票号
static List<bool> entering = new List<bool>(threads); //记录线程是否要进入
public static void addLock(int pid) // thread ID
{
//Console.WriteLine(pid);
entering[pid] = true;
int max = 0;
for (int i = 0; i < threads; ++i)
{
int current = ticket[i];
if (current > max)
{
max = current;
}
}
ticket[pid]=max+1;
entering[pid]=false;
for (int i = 0; i < ticket.Count; ++i)
{
if (i != pid)
{
while (entering[i] == true) { ; } // wait while other thread picks a ticket
while (ticket[i] != 0 && ( ticket[pid] > ticket[i] ||
(ticket[pid] == ticket[i] && pid > i)))
{ ; }
}
}
// The critical section goes here...
}
public static void unlock(int pid)
{
ticket[pid] = 0;
}
public static void changeValue(object pid)
{
int p = Convert.ToInt32(pid.ToString());
addLock(p);
for (int i = 0; i < total; i++)
{
num = num + 1;
Console.WriteLine(num);
}
unlock(p);
}
public static void readValue(object pid)
{
int p = Convert.ToInt32(pid.ToString());
addLock(p);
for (int i = 0; i < total; i++)
{
num = num - 1;
Console.WriteLine(num);
}
unlock(p);
}
static void Main(string[] args)
{
ticket = new List<int>(threads);
entering = new List<bool>(threads);
for (int i = 0; i < threads;i++ )
{
ticket.Add(-1);
entering.Add(false);
}
for (int i = 0; i < total; i++)
{
data[i] = 0;
}
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int num = 10;
Thread[] t = new Thread[num];
t[0] = new Thread(new ParameterizedThreadStart(changeValue));
t[1] = new Thread(new ParameterizedThreadStart(readValue));
t[2] = new Thread(new ParameterizedThreadStart(readValue));
t[3] = new Thread(new ParameterizedThreadStart(changeValue));
stopwatch.Start();
t[0].Start(0);
t[1].Start(1);
t[2].Start(2);
t[3].Start(3);
t[0].Join();
t[1].Join();
t[2].Join();
t[3].Join();
stopwatch.Stop();
Console.WriteLine("运行时间" + stopwatch.ElapsedMilliseconds.ToString());
Console.ReadKey();
}
}
}