zoukankan      html  css  js  c++  java
  • C#简单多线程使用(同步和优先权)

    题目:

    麦当劳有两个做汉堡的厨师(工号:11,12)和三个销售人员(工号:21,22,23)。

    厨师生产汉堡,并负责将做好的汉堡放入货架,货架台大小有限,最多放6个汉堡,11和12不能同时往货架台上放汉堡,11具有优先权。

    销售人员负责销售食品,三个销售人员取食品时,货架不能为空,三人不能同时取,23优先权最高,21最低。21卖的最快,取得频率最高,22次之。

    一天的工作量是销售70个汉堡。

    一些概念了解  

    阻塞:函数返回结果之前,线程被挂起

    非阻塞:函数执行完立即返回,不会阻塞线程

    同步:函数没有执行完不返回,线程被挂起;

    异步:函数立即返回,结果通过事件或是信号通知调用者; 

    同步消息处理就好比linux中简单的read/write操作,它们需要等待这操作成功才能返回;而异步处理机制就是类似于select/poll之类的多路复用IO操作,当所关注的消息被触发时,由消息触发机制通知触发对消息的处理.

    进程:当一个程序运行时,它就是一个进程,进程包括运行中的程序所使用到的内存和系统资源,同时一个进程可以包括多个线程

    线程:线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。

    多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。时间片有CPU分配运行!

    Thread主要方法:Strart(),Sleep(int),Abort(),Suspend(),Resume()

    线程优先级:在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。

    线程同步(Framework中已经为我们提供了三个加锁的机制,分别是Monitor类、Lock关键字和Mutex类。

    ):

    a.C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。

    在C#中,关键字lock定义如下:

    lock(expression表达式) statement_block

    b.Monitor主要用法

    Monitor.Enter(obj);

    (expression)

    Monitor.Exit(obj);

    c.Mutex用法

    Mutex mutex = new Mutex();

    mutex.WaitOne();

    (expression)

    mutex.ReleaseMutex();

    举个lock互斥例子(包括多线程使用和多线程优先权、同步使用):

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Text;  
    4. using System.Threading;  
    5. namespace TestThread  
    6. {  
    7.     class Program  
    8.     {  
    9.         private static object lockObject = new object();  
    10.         private static object lockObject2 = new object();  
    11.         private static int iGetHBnum = 0;  
    12.         private static int iPutHBnum = 0;  
    13.         private static int count21 = 0;  
    14.         private static int count22 = 0;  
    15.         private static int count23 = 0;  
    16.   
    17.         private static int count11 = 0;  
    18.         private static int count12 = 0;  
    19.   
    20.         static void Main(string[] args)  
    21.         {  
    22.             Console.WriteLine("主线程运行,线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());  
    23.   
    24.             Thread chushi1 = new Thread(PutHB);  
    25.             chushi1.Priority = ThreadPriority.AboveNormal;  
    26.             chushi1.Name = "11";  
    27.             chushi1.Start();  
    28.           
    29.             Thread chushi2 = new Thread(PutHB);  
    30.             chushi2.Priority = ThreadPriority.Normal;  
    31.             chushi2.Name = "12";  
    32.             chushi2.Start();          
    33.        
    34.   
    35.             Thread Consume21 = new Thread(GetHB);  
    36.             Consume21.Priority = ThreadPriority.Normal;  
    37.             Consume21.Name = "21";  
    38.             Consume21.Start();  
    39.   
    40.             Thread Consume22 = new Thread(GetHB);  
    41.             Consume22.Priority = ThreadPriority.Normal;  
    42.             Consume22.Name = "22";  
    43.             Consume22.Start();  
    44.   
    45.             Thread Consume23 = new Thread(GetHB);  
    46.             Consume23.Priority = ThreadPriority.Normal;  
    47.             Consume23.Name = "23";  
    48.             Consume23.Start();  
    49.   
    50.             Console.ReadKey();  
    51.         }  
    52.   
    53.         public static void PutHB()  
    54.         {  
    55.             string strID = Thread.CurrentThread.Name.ToString();  
    56.             Console.WriteLine("{0}厨师开始制作汉堡,,,", strID);  
    57.   
    58.             while (true)  
    59.             {  
    60.   
    61.                 if (iPutHBnum >= 6)  
    62.                 {  
    63.                     Console.WriteLine("厨师{0},最多放6个汉堡,请让销售员取再放!", strID);  
    64.                     Thread.Sleep(1000);  
    65.                 }  
    66.                 else  
    67.                 {       
    68.   
    69.                     if (iGetHBnum >= 70 ||count11 + count12 >= 70)  
    70.                     {  
    71.                         if (strID == "11")  
    72.                         {  
    73.                             Console.WriteLine("厨师{0},在货架放共放{1}汉堡!", strID, count11);  
    74.                         }  
    75.                         else if (strID == "12")  
    76.                         {  
    77.                             Console.WriteLine("厨师{0},在货架放共放{1}汉堡!", strID, count12);  
    78.                         }  
    79.                         break;  
    80.                     }  
    81.   
    82.                     lock (lockObject)  
    83.                     {  
    84.                         iPutHBnum++;  
    85.                          
    86.                     }  
    87.   
    88.                     if (strID == "11")  
    89.                     {  
    90.                         count11++;  
    91.                         Console.WriteLine("厨师{0},在货架放已放{1}汉堡! 现在货架有{2}汉堡!", strID,count11, iPutHBnum);  
    92.                     
    93.                     }  
    94.                     else if (strID == "12")  
    95.                     {  
    96.                         count12++;  
    97.                         Console.WriteLine("厨师{0},在货架放已放{1}汉堡! 现在货架有{2}汉堡!", strID, count12, iPutHBnum);  
    98.                 
    99.                     }  
    100.                 }  
    101.             }  
    102.   
    103.         }  
    104.   
    105.         public static void GetHB()  
    106.         {  
    107.             string strID = Thread.CurrentThread.Name.ToString();  
    108.             Console.WriteLine("{0}销售员取汉堡,,,", strID);  
    109.               
    110.                 while (true)  
    111.                 {   
    112.                     if (iPutHBnum <= 0)  
    113.                     {  
    114.                         Thread.Sleep(1000);  
    115.                         Console.WriteLine("{0}货架台已0个汉堡,请等待厨师制作!", strID);  
    116.                          
    117.                     }  
    118.                     else  
    119.                     {  
    120.                         lock (lockObject2)  
    121.                         {   
    122.                             iGetHBnum++;  
    123.                             iPutHBnum--;     
    124.                         }  
    125.   
    126.                         if (strID == "23")  
    127.                         {  
    128.                             count23++;  
    129.                             Console.WriteLine("23号销售员已销售---{0}!", count23);  
    130.                             Thread.Sleep(3000);  
    131.                         }  
    132.                         else if (strID == "22")  
    133.                         {  
    134.                             count22++;  
    135.                             Console.WriteLine("22号销售员已销售---{0}!", count22);  
    136.                             Thread.Sleep(2000);  
    137.                         }  
    138.                         else if (strID == "21")  
    139.                         {  
    140.                             count21++;  
    141.                             Console.WriteLine("21号销售员已销售---{0}!", count21);  
    142.                             Thread.Sleep(1000);  
    143.                         }  
    144.                          
    145.                     }  
    146.   
    147.                     if (iGetHBnum >= 70)  
    148.                     {  
    149.                         Console.WriteLine("销售完!");  
    150.   
    151.                         if (strID == "23")  
    152.                         {  
    153.                             Console.WriteLine("23号销售员销售总数:{0}", count23);  
    154.                         }  
    155.                         else if (strID == "22")  
    156.                         {  
    157.                             Console.WriteLine("22号销售员销售总数:{0}", count22);  
    158.                         }  
    159.                         else if (strID == "21")  
    160.                         {  
    161.                             Console.WriteLine("21号销售员销售总数:{0}", count21);  
    162.                         }  
    163.                         break;  
    164.                     }  
    165.   
    166.   
    167.                 }  
    168.               
    169.   
    170.   
    171.         }  
    172.     }  
    173. }  

    结果:

    lock可以用Monitor,Mutex替代

                        Monitor.Enter(lockObject);

                       

                            iPutHBnum++;

                           

                        Monitor.Exit(lockObject);

    或者

                        mutex1.WaitOne();  

                     

                            iPutHBnum++;

                        mutex1.ReleaseMutex();

  • 相关阅读:
    Swift代码实现加载WEBVIEW
    android 图片压缩
    Android图片压缩(质量压缩和尺寸压缩)
    Android压缩图片到100K以下并保持不失真的高效方法
    android图片压缩的3种方法实例
    几种颜色模型的转换公式
    RGB HSV HLS三种色彩模式转换(C语言实现)
    由RGB到HSV颜色空间的理解
    BZOJ 1052 HAOI2007 覆盖问题 二分法答案+DFS
    插入排序算法
  • 原文地址:https://www.cnblogs.com/rr163/p/3967693.html
Copyright © 2011-2022 走看看