天天看点

C#奇数线程和偶数线程,依次输出1到100

C#奇数线程和偶数线程,依次输出1到100,同学们来看看如何实现的 ​​​​

program.cs文件包含的代码

using CSharpDemo.instance;
using System.Threading;


//第一个任务 奇数线程和偶数线程,依次输出1到100
VisualService.Instance.LaunchOutputOddAndEven();

Thread.Sleep(1000);
//第二个任务
VisualService.Instance.Run();      
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDemo.instance;

/// <summary>
/// 懒汉式单例模式
/// PS:一般用.net core 的话都是通过 依赖注入去实现 IServiceCollection 去注入 
/// AddSingleTon 或者 AddScoped  或者 AddTransient
/// </summary>
public class VisualService
{
    //1、私有构造函数
    private VisualService() { }
    //2、静态私有变量
    private static VisualService _instance;

    //3、实例化一个锁对象,主要用于同步线程
    private static readonly object locker = new object();

    //4、获取静态单实例属性
    public static VisualService Instance
    {
        get
        {
            //一旦实例初始化就绪,就需要这个条件来避免线程在锁上等待
            if (_instance == null)
            {
                //当项目刚刚启动,由于没有单实例,多个线程可以同时通过前一个条件并且几乎同时到达这点
                //他们当中的第一个获得锁的线程继续前行,剩余的线程仍在锁上等待
                lock (locker)
                {
                    //获取锁的第一个线程到达这个条件,并进入创建单实例,一旦它离开锁,一直在等待锁释放的线程就可能会跑到这部分
                    //但是由于Singleton _instance字段已经初始化了,线程则不会在去创建对象
                    if (_instance == null)
                    {
                        _instance = new VisualService();
                    }
                }
            }
            return _instance;
        }
    }

    public void Run()
    {
        Console.WriteLine("\t\n任务二:单例类的Run方法");

    }

    /// <summary>
    /// 发起奇线程和偶线程依次输出1到100的数
    /// </summary>
    public void LaunchOutputOddAndEven()
    {
        List<AutoResetEvent> listAre = new List<AutoResetEvent>()
            {
                new AutoResetEvent(false),//第一个用来控制 奇数线程
                new AutoResetEvent(false)//第二个用来控制 偶数线程
            };
        Thread threadEven = new Thread(new ParameterizedThreadStart(PrintEven!));
        threadEven.Start(listAre); //偶数线程
        Thread threadOdd = new Thread(new ParameterizedThreadStart(PrintOdd!));
        threadOdd.Start(listAre); //奇数线程
    }

    private void PrintEven(object resetEvenObject)
    {
        var resetEvents = resetEvenObject as IList<AutoResetEvent>;
        if (resetEvents != null)
        {
            var oddResetEvent = resetEvents[0];
            var evenResetEvent = resetEvents[1];

            for (int i = 1; i < 100; i += 2)
            {
                //设置奇数线程无信号
                oddResetEvent.WaitOne();
                Console.WriteLine($"偶数:{i + 1}");//改变后的i加1就会由奇数变偶数了
                                                 //设置偶数线程有信号
                evenResetEvent.Set();
                //Thread.Sleep(1000);
            }
        }
    }

    private void PrintOdd(object resetEvenObject)
    {
        var resetEvents = resetEvenObject as IList<AutoResetEvent>;
        if (resetEvents != null)
        {
            var oddResetEvent = resetEvents[0];
            var evenResetEvent = resetEvents[1];
            evenResetEvent.Set();
            for (int i = 0; i < 100; i += 2)
            {//这里的i是偶数
                evenResetEvent.WaitOne();
                Console.WriteLine($"奇数:{i + 1}");//改变后的i加1就会由偶数变奇数了
                oddResetEvent.Set();
                //Thread.Sleep(1000);
            }
        }
    }
}