几组线程同步代码测试

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的使用还是要慎重

时间: 2024-08-19 03:54:31

几组线程同步代码测试的相关文章

多线程之:线程同步代码块

java中使用关键字synchronized进行线程同步,有四中同步块: 1.实例方法 2.静态方法 3.实例方法中的同步块 4.静态方法中的同步块 实例方法同步:在方法申明中使用synchronized 关键字,同步在拥有该方法的对象上 1 public synchronized void increase(){ 2 this.id++; 3 } 静态方法同步:与实例方法同步一样,在方法申明中使用synchronized 关键字,同步在拥有该方法的类对象上,同时只允许一个线程执行同一个类中的静

windows 线程同步学习测试-1

环境win7旗舰64位系统,vs2013,AMD fx™4100 Auad-core processor ,8G内存, 看<windows核心编程>线程同步一章,看到有说g_x++会不同步的问题,试着写些代码加深印象.发现+1太快了,看不出效果,于是for循环了1亿次.代码如下: #include "stdafx.h" using std::cout; using std::endl; using std::cin; unsigned __stdcall ThreadFun

C# 线程同步代码

#define CODE1 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SomeDemo { public cla

多线程(6)线程同步

使用多线程很容易,但是如果多个线程同时访问一个共享资源时而不加以控制,就会导致数据损坏.所以多线程并发时,必须要考虑线程同步(或称线程安全)的问题. 什么是线程同步 多个线程同时访问共享资源时,使多个线程顺序(串行)访问共享资源的机制. 注意: 1,共享资源,比如全局变量和静态变量. 2,访问,一般指写操作,读操作无需考虑线程同步. 3,串行,指当一个线程正在访问共享资源时,其它线程等待,直到该线程释放锁. 线程同步带来哪些问题 如果能保证多个线程不会同时访问共享资源,那么就不需要考虑线程同步.

IOS 多线程,线程同步的三种方式

一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IOS中我们一般情况下使用以下三种线程同步代码方式: 第一种和第二种代码同步的使用方法,一般情况下我们只需要使用NSLock和NSCondition申明2个属性.然后给此属性赋对应的值.那么即可作为安全防控的线程手段. 同时也可以保证线程的资源安全. 1:NSLock方式 [xxxlock   lock] //上锁 同步代码块 [xxxlock   unlock]//解锁 2:NSCondition

mfc小工具开发之定时闹钟之---多线程急线程同步

一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等.用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等.但对于Win32的API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务. 在MFC中,一般用全局函数Afx

使用Win32 API实现生产者消费者线程同步

使用win32 API创建线程,创建信号量用于线程的同步 创建信号量 语法例如以下 HANDLE semophore; semophore = CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName); CreateSemophore函数的原型例如以下: HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreA

Visual C++线程同步技术剖析:临界区,事件,信号量,互斥量

转自: 使线程同步 在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作.更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解.正常情况下对这种处理结果的了解应当在其处理任务完成后进行. 如果不采取适当的措施,其他线程往往会在线程处理任务结束前就去访问处理结果,这就很有可能得到有关处理结果的错误了解.例如,多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题.如果一个线程负责改变此变量的值,而其他线程负责同时读取变量内容,则不能保证读取到的数

写2个线程,一个打印1-52,一个打印A-Z,打印顺序是12A34B。。。(采用同步代码块和同步方法两种同步方法)

1.同步方法 package Synchronized; /************************************同步方法****************************************/ public class PrintTest { public static void main(String[] args) { Print p = new Print(); Thread t1 = new PrintNumber(p); Thread t2 = new P