Pulse vs PulseAll

來源:互聯網
上載者:User
      What's difference between Pulse and PulseAll which are static methods in Monitor class ? Let us have a look at msdn introduction at first. 
      Pulse  :     Notifies a thread in the waiting queue of a change in the locked object's state. 
      PulseAll :  Notifies all waiting threads of a change in the object's state.

      We have to know waiting queue and ready queue in order to understand multi-thread and lock. All threads in ready queue have chances to be executed, and all threads in waiting queue must enter ready queue before execution. When we call Monitor.Wait(), the thread will step into waiting queue and realse its lock. Simultaneously, a single thread will be moved to ready queue if Monitor.Pulse() is called, or all threads will be done if PulseAll() is called. In the later scenario, all threads have chance to run. But in multi-thread programming, when a thread gets a chance, it will try to get a lock in our code generally, then other threads  related to that lock cannot go on. This is also the reason why a few people don't understand their difference. Souce code is the best way to make an explanation.

   

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Collections.Specialized;


namespace PulseVsPulseAll
{
    /**//// <summary>
    /// The order of this program is to show difference between Pulse and PulseAll
    /// </summary>
    class Program
    {

        public static StringCollection list = new StringCollection();


        static void Main(string[] args)
        {
            Thread t1 = new Thread(new ThreadStart(Fun1));
            t1.Name = "t1";
            Thread t2 = new Thread(new ThreadStart(Fun2));
            t2.Name = "t2";

            int count = 0;

            Console.WriteLine("Press Enter to Start");
            Console.ReadLine();
            t1.Start();
            t2.Start();

            while (true)
            {
               Thread.Sleep(3000);

                count++;
                string hotdog = count.ToString() + "*" + "hotdog";
                Console.WriteLine();
                Console.WriteLine("Producer: "+hotdog);

                try
                {
                    Monitor.Enter(list);

                    list.Add(hotdog);

                    Monitor.PulseAll(list); // Try Monitor.PulseAll(list); which will induce other codes to throw exception,
                                         // because it will notify all waiting threads binding to list.

                }
                finally
                {
                    Monitor.Exit(list);
                }
               
            }


            t1.Join();
            t2.Join();

            Console.ReadLine();
        }

        public static void Fun1()
        {
            while (true)
            {

                    if (list.Count == 0)
                    {
                        lock (list)
                        {
                            Monitor.Wait(list);
                            Console.WriteLine("Fun1#" + "Released");
                        }
                    }
                    else
                    {
                        Thread.Sleep(1000);
                        string hotdog = list[0];
                        list.RemoveAt(0);
                        Console.WriteLine("Fun1" + "#" + hotdog);

                    }
   
            }
        }

        public static void Fun2()
        {
            while (true)
            {
               
                    if (list.Count == 0)
                    {
                        lock(list)
                        {
                            Monitor.Wait(list);
                            Console.WriteLine("Fun2#" + "Released");
                        }
                    }
                    else
                    {
                        Thread.Sleep(1000);
                        string hotdog = list[0];
                        list.RemoveAt(0);
                        Console.WriteLine("Fun2" + "#" + hotdog);
                       
                    }

             }
            
        }
    }
}

 

The code is urgly, but can explain the problem well. If we cover the entire "if" branch code In Fun1() and Fun2 with "lock", it won't be direct to show the question.
 When the main thread creates a hotdog, it will notify one of the current wainting threads in waiting queue to enter ready queue and run, it can work well. But when we take place of Pulse() with PulseAll(), both of the current waiting threads will get chance to run, and will generate race condition. In this program, it will throw an exception, because both threads fetch a hotdog, one of them will fail.
  
    Practise to improve English. 
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.