题目说明

题目:两个线程交替打印输出数字1-100,一个线程只打印偶数,另一个只打印奇数,并且要求按顺序输出。
最近看到了这个题目,想到了几种实现的方式,记录一下,如果有写的不对的地方,欢迎指正!!!

代码实现

方法一

可以通过两个外部的变量,去控制是打印奇数还是偶数,下面是实现的代码

class Program
    {
        public static int i = 1;
        public static bool isprintOddNumber = false;//控制基数的变量,判断是否可以进行打印奇数
        public static bool isprintEvenNumber = false;//控制偶数的变量,判断是否可以进行打印偶数
        static void Main(string[] args)
        {
            Thread thOdd = new Thread(printNumOdd);//奇数线程
            Thread thComplex = new Thread(printNumComplex);//偶数线程
            isprintOddNumber = true;//刚开始的时候可以打印奇数
            isprintEvenNumber = false;//偶数控制不能打印
            thOdd.Name = "奇数";
            thComplex.Name = "偶数";
            thOdd.Start();
            thComplex.Start();
            Console.Read();
        }
        private static void printNumOdd()
        {
            while(i<100)
            {
                if (i % 2 != 0)
                {
                    if (isprintOddNumber) 
                    {
                        Console.WriteLine($"{Thread.CurrentThread.Name}线程,输出的数字为奇数:{i}");
                        isprintOddNumber = false;//打印完奇数后,控制奇数不能打印
                        isprintEvenNumber = true;//打印完奇数后,控制下一次可以打印偶数
                        i++;
                    }
                }
            }
        }
        /// <summary>
        /// 添加偶数
        /// </summary>
        private static void printNumComplex()
        {
            while(i<=100)
            {
                if (i % 2 == 0)
                {
                    if (isprintEvenNumber)
                    {
                        Console.WriteLine($"{Thread.CurrentThread.Name}线程,输出的数字为偶数:{i}");
                        isprintOddNumber = true;//打印完偶数后,控制偶数不能打印
                        isprintEvenNumber = false;//打印完偶数后,控制下一次可以打印奇数
                        i++;
                    }
                    
                }
            }
        }
    }

可以看到结果是符合要求的,交替输出了,也按照顺序输出了

两个线程交替打印数字 java 创建两个线程交替打印1-100_c#

方法二

可以用加锁的方式实现,也可以实现要求的效果

class Program
    {
        public static int i = 0;
        static readonly object objSync = new object();
        static void Main(string[] args)
        {
            Thread thOdd = new Thread(printNumOdd);
            Thread thComplex = new Thread(printNumComplex);
            thOdd.Name = "奇数";
            thComplex.Name = "偶数";
            thOdd.Start();
            thComplex.Start();
            Console.Read();
        }
        private static void printNumOdd()
        {
            while(i<100)
            {
                lock (objSync)
                {
                    if (i % 2 != 0)
                    {  
                         Console.WriteLine($"{Thread.CurrentThread.Name}线程,输出的数字为奇数:{i}");
                         i++;
                    }                  
                }     
            }
        }
        /// <summary>
        /// 添加偶数
        /// </summary>
        private static void printNumComplex()
        {
            while(i<=100)
            {
                
                lock (objSync)
                {
                    if (i % 2 == 0)
                    {  
                         Console.WriteLine($"{Thread.CurrentThread.Name}线程,输出的数字为偶数数:{i}");
                         i++;
                    }                  
                }     
            }
        }
    }

两个线程交替打印数字 java 创建两个线程交替打印1-100_加锁_02


前面两种方法都实现了两个线程交替顺序输出的效果,但是可能在过程中两个线程的执行并不是交替进行的,可能会存在某个线程多次抢到了资源,但是因为没有符合条件,导致了资源的浪费

两个线程交替打印数字 java 创建两个线程交替打印1-100_i++_03

方法三

可以使用AutoResetEvent (允许线程之间通过信号进行通信)用一个指示是否将初始状态设置为终止的布尔值初始化该类的新实例。
线程可以通过调用AutoResetEvent对象的WaitOne()方法进入等待状态,然后另外一个线程通过调用Set()方法取消等待的状态。

class Program
    {
        public static int i = 0;
        public static AutoResetEvent mreWaitOddNumber = new AutoResetEvent(false);
        public static AutoResetEvent mreWaitEvenNumber = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            Thread thOdd = new Thread(printNumOdd);
            Thread thComplex = new Thread(printNumComplex);
            thOdd.Name = "奇数";
            thComplex.Name = "偶数";
            thOdd.Start();
            thComplex.Start();
            Console.Read();
        }
        private static void printNumOdd()
        {
            mreWaitOddNumber.WaitOne();
            while (i < 100)
            {
                if (i % 2 != 0)
                {
                    Console.WriteLine($"{Thread.CurrentThread.Name}线程,输出的数字为奇数:{i}");
                    i++;
                }
                mreWaitEvenNumber.Set();//唤醒偶数线程
                mreWaitOddNumber.WaitOne();//阻塞奇数线程
            }
        }
        private static void printNumComplex()
        {
            while (i <= 100)
            {

                if (i % 2 == 0)
                {
                    Console.WriteLine($"{Thread.CurrentThread.Name}线程,输出的数字为偶数:{i}");
                    i++;                    
                }
                mreWaitOddNumber.Set();//给奇数线程信号
                mreWaitEvenNumber.WaitOne();//阻塞偶数线程
            }
        }
    }

两个线程交替打印数字 java 创建两个线程交替打印1-100_c#_04


上面就是分享的三种方式,也还有其他的方法,这里也不一一赘述了,刚接触到这块内容,如果有写的不对的地方,或者表述不准确的,也欢迎指正!!!