几组线程同步代码测试
Posted 遗忘海岸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了几组线程同步代码测试相关的知识,希望对你有一定的参考价值。
1.
public class A { public void MA() { lock (typeof(A)) { Thread.Sleep(5000); Console.WriteLine("MA:" +DateTime.Now); } } public void MB() { Thread.Sleep(100); Console.WriteLine("MB:" + DateTime.Now); } } } private void button4_Click(object sender, EventArgs e) { var a=new A(); var t = new Thread(a.MA); t.Start(); Thread.Sleep(100); var t2 = new Thread(a.MB); t2.Start(); }
MB会正常输出,只有lock了同个对象的代码段会产生同步等待
2.
private void button5_Click(object sender, EventArgs e) { SendCount = 0; var arr = RequestStr3.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var bytes = new List<byte>(); foreach (var item in arr) { bytes.Add(byte.Parse(item, NumberStyles.HexNumber)); } var paket = nRadiusPaket.Parser(bytes.ToArray()); Stopwatch sw = new Stopwatch(); sw.Start(); for (int j = 0; j < 30; j++) { ThreadPool.QueueUserWorkItem(o => { for (int i = 0; i < 100; i++) { try { UdpClient udp = new UdpClient(); udp.Connect("192.168.9.5", 1812); udp.Send(paket.Paket, paket.Length); System.Net.IPEndPoint RemoteIpEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0); var rec = udp.Receive(ref RemoteIpEndPoint); var retPaket = nRadiusPaket.Parser(rec); Interlocked.Increment(ref SendCount); } catch (Exception ex) { Console.WriteLine(ex.Message); continue; } } // Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId + ",退出!"); }, null); } long bTime = Environment.TickCount; while (SendCount < 3000 && (Environment.TickCount - bTime) < 10000) { Application.DoEvents(); } sw.Stop(); Console.WriteLine("SendCount:" + SendCount); Console.WriteLine("耗时:" + sw.ElapsedMilliseconds); //Console.WriteLine(Encoding.ASCII.GetString(rec)); //Console.WriteLine("---------------------"); //File.WriteAllText(@"C:\\rpak.txt", BitConverter.ToString(rec)); }
使用 Interlocked.Increment(ref SendCount);进行同步
3.使用Barrier,(代码摘自:.NET 4.0面向对象编程漫谈)
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UseBarrier { /// <summary> /// 线程参与者必须实现的接口 /// </summary> public interface IParticipant { void Go(); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace UseBarrier { /// <summary> /// 张三 /// </summary> public class ZhangSan:IParticipant { /// <summary> /// 用于生成随机暂停的时间 /// </summary> private Random ran = new Random(); public void Go() { Console.WriteLine("张三出门,挤公交车……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100,300)); Console.WriteLine("张三下了公交车,到了地铁站,买票坐地铁……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100,300)); Console.WriteLine("张三到了鸟巢大门……"); Program.barrier.SignalAndWait(); //等待会合 //开始参观 Console.WriteLine("张三在参观……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Program.barrier.SignalAndWait(); //参观结束 Console.WriteLine("张三离开了鸟巢,到了地铁站,买票坐地铁回家……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Console.WriteLine("张三离开了地铁站,坐公交车回家……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Console.WriteLine("张三回到家了!"); Program.barrier.SignalAndWait();//回到家了! } } /// <summary> /// 李四 /// </summary> public class LiSi : IParticipant { /// <summary> /// 用于生成随机暂停的时间 /// </summary> private Random ran = new Random(); public void Go() { Console.WriteLine("李四出门,到了地铁站,买票坐地铁……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Console.WriteLine("李四到了鸟巢大门……"); Program.barrier.SignalAndWait(); //等待会合 //开始参观 Console.WriteLine("李四在参观……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Program.barrier.SignalAndWait(); //参观结束 Console.WriteLine("李四离开了鸟巢,到了地铁站,买票坐地铁回家……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Console.WriteLine("李四回到家了!"); Program.barrier.SignalAndWait();//回到家了! } } /// <summary> /// 王五 /// </summary> public class WangWu : IParticipant { /// <summary> /// 用于生成随机暂停的时间 /// </summary> private Random ran = new Random(); public void Go() { Console.WriteLine("王五出门,步行去鸟巢……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Console.WriteLine("王五到了鸟巢大门……"); Program.barrier.SignalAndWait(); //等待会合 //开始参观 Console.WriteLine("王五在参观……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Program.barrier.SignalAndWait(); //参观结束 Console.WriteLine("王五离开了鸟巢,步行回家……"); //随机暂停1到3秒 Thread.Sleep(ran.Next(100, 300)); Console.WriteLine("王五回到家了!"); Program.barrier.SignalAndWait();//回到家了! } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace UseBarrier { class Program { public static Barrier barrier = null; static void Main(string[] args) { Action<Barrier> PhaseAction = delegate(Barrier barier) { switch (barrier.CurrentPhaseNumber) { case 0: Console.WriteLine("\\n==============================="); Console.WriteLine("\\n同步阶段一:张三、李四和王五都到达了鸟巢,开始参观……"); Console.WriteLine("\\n==============================="); break; case 1: Console.WriteLine("\\n==============================="); Console.WriteLine("等待10秒!"); Thread.Sleep(10000); Console.WriteLine("\\n同步阶段二:参观结束,张三、李四和王五开始回家……"); Console.WriteLine("\\n==============================="); break; case 2: Console.WriteLine("\\n==============================="); Console.WriteLine("\\n同步阶段三:所有人都回到了家,啊,多么快乐的一天!\\n"); Console.WriteLine("\\n==============================="); break; } }; //有3个线程参与 barrier = new Barrier(3, PhaseAction); //创建3个参与者对象 List<IParticipant> Participants = new List<IParticipant> { new ZhangSan(), new LiSi(), new WangWu() }; Console.WriteLine("敲任意键Barrier示例开始演示..."); Console.ReadKey(true); Console.WriteLine("\\n==============================="); //启动3个线程 List<Thread> ths = new List<Thread>(); foreach (IParticipant man in Participants) { Thread th = new Thread(man.Go); ths.Add(th); th.Start(); } //等待所有线程运行结束 foreach (Thread th in ths) { th.Join(); } Console.WriteLine("敲任意键退出……"); Console.ReadKey(); } } }
采用Barrier方式改写上面2的代码后发现,时间由原来的1.5秒变成42秒,Barrier的使用还是要慎重
以上是关于几组线程同步代码测试的主要内容,如果未能解决你的问题,请参考以下文章