C#简单多线程同步和优先权用法实例

本文实例讲述了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类。

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

lock(expression表达式) statement_block

② Monitor主要用法

Monitor.Enter(obj);
(expression)
Monitor.Exit(obj);

③ Mutex用法

Mutex mutex = new Mutex();
mutex.WaitOne();
(expression)
mutex.ReleaseMutex();

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

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TestThread
{
  class Program
  {
    private static object lockObject = new object();
    private static object lockObject2 = new object();
    private static int iGetHBnum = 0;
    private static int iPutHBnum = 0;
    private static int count21 = 0;
    private static int count22 = 0;
    private static int count23 = 0;
    private static int count11 = 0;
    private static int count12 = 0;
    static void Main(string[] args)
    {
      Console.WriteLine("主线程运行,线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
      Thread chushi1 = new Thread(PutHB);
      chushi1.Priority = ThreadPriority.AboveNormal;
      chushi1.Name = "11";
      chushi1.Start();
      Thread chushi2 = new Thread(PutHB);
      chushi2.Priority = ThreadPriority.Normal;
      chushi2.Name = "12";
      chushi2.Start();     

      Thread Consume21 = new Thread(GetHB);
      Consume21.Priority = ThreadPriority.Normal;
      Consume21.Name = "21";
      Consume21.Start();
      Thread Consume22 = new Thread(GetHB);
      Consume22.Priority = ThreadPriority.Normal;
      Consume22.Name = "22";
      Consume22.Start();
      Thread Consume23 = new Thread(GetHB);
      Consume23.Priority = ThreadPriority.Normal;
      Consume23.Name = "23";
      Consume23.Start();
      Console.ReadKey();
    }
    public static void PutHB()
    {
      string strID = Thread.CurrentThread.Name.ToString();
      Console.WriteLine("{0}厨师开始制作汉堡,,,", strID);
      while (true)
      {
        if (iPutHBnum >= 6)
        {
          Console.WriteLine("厨师{0},最多放6个汉堡,请让销售员取再放!", strID);
          Thread.Sleep(1000);
        }
        else
        {
          if (iGetHBnum >= 70 ||count11 + count12 >= 70)
          {
            if (strID == "11")
            {
              Console.WriteLine("厨师{0},在货架放共放{1}汉堡!", strID, count11);
            }
            else if (strID == "12")
            {
              Console.WriteLine("厨师{0},在货架放共放{1}汉堡!", strID, count12);
            }
            break;
          }
          lock (lockObject)
          {
            iPutHBnum++;
          }
          if (strID == "11")
          {
            count11++;
            Console.WriteLine("厨师{0},在货架放已放{1}汉堡! 现在货架有{2}汉堡!", strID,count11, iPutHBnum);
          }
          else if (strID == "12")
          {
            count12++;
            Console.WriteLine("厨师{0},在货架放已放{1}汉堡! 现在货架有{2}汉堡!", strID, count12, iPutHBnum);
          }
        }
      }
    }
    public static void GetHB()
    {
      string strID = Thread.CurrentThread.Name.ToString();
      Console.WriteLine("{0}销售员取汉堡,,,", strID);
        while (true)
        {
          if (iPutHBnum <= 0)
          {
            Thread.Sleep(1000);
            Console.WriteLine("{0}货架台已0个汉堡,请等待厨师制作!", strID);
          }
          else
          {
            lock (lockObject2)
            {
              iGetHBnum++;
              iPutHBnum--;
            }
            if (strID == "23")
            {
              count23++;
              Console.WriteLine("23号销售员已销售---{0}!",count23);
              Thread.Sleep(3000);
            }
            else if (strID == "22")
            {
              count22++;
              Console.WriteLine("22号销售员已销售---{0}!", count22);
              Thread.Sleep(2000);
            }
            else if (strID == "21")
            {
              count21++;
              Console.WriteLine("21号销售员已销售---{0}!", count21);
              Thread.Sleep(1000);
            }
          }
          if (iGetHBnum >= 70)
          {
            Console.WriteLine("销售完!");
            if (strID == "23")
            {
              Console.WriteLine("23号销售员销售总数:{0}", count23);
            }
            else if (strID == "22")
            {
              Console.WriteLine("22号销售员销售总数:{0}", count22);
            }
            else if (strID == "21")
            {
              Console.WriteLine("21号销售员销售总数:{0}", count21);
            }
            break;
          }
        }
    }
  }
}

运行结果如下图所示:

lock可以用Monitor,Mutex替代:

Monitor.Enter(lockObject);
iPutHBnum++;
Monitor.Exit(lockObject);

或者:

mutex1.WaitOne();
iPutHBnum++;
mutex1.ReleaseMutex();

希望本文所述对大家的C#程序设计有所帮助。

(0)

相关推荐

  • 详解C#多线程之线程同步

    多线程内容大致分两部分,其一是异步操作,可通过专用,线程池,Task,Parallel,PLINQ等,而这里又涉及工作线程与IO线程:其二是线程同步问题,鄙人现在学习与探究的是线程同步问题. 通过学习<CLR via C#>里面的内容,对线程同步形成了脉络较清晰的体系结构,在多线程中实现线程同步的是线程同步构造,这个构造分两大类,一个是基元构造,一个是混合构造.所谓基元则是在代码中使用最简单的构造.基原构造又分成两类,一个是用户模式,另一个是内核模式.而混合构造则是在内部会使用基元构造的用户模

  • 详细解析C#多线程同步事件及等待句柄

    最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading.WaitHandle.WaitOne .System.Threading.WaitHandle.WaitAny和System.Threading.WaitHandle.WaitAll ,下面我们一最初学者的角度来看,多线程之间的同步. 假设有这样的一个场

  • C#实现多线程的同步方法实例分析

    本文主要描述在C#中线程同步的方法.线程的基本概念网上资料也很多就不再赘述了.直接接入 主题,在多线程开发的应用中,线程同步是不可避免的.在.Net框架中,实现线程同步主要通过以下的几种方式来实现,在MSDN的线程指南中已经讲了几种,这里结合作者实际中用到的方式一起说明一下. 1. 维护自由锁(InterLocked)实现同步 2. 监视器(Monitor)和互斥锁(lock) 3. 读写锁(ReadWriteLock) 4. 系统内核对象 1) 互斥(Mutex), 信号量(Semaphore

  • C#多线程及同步示例简析

    60年代,在OS中能拥有资源和独立运行的基本单位是进程,然而随着计算机技术的发展,进程出现了很多弊端,一是由于进程是资源拥有者,创建.撤消与切换存在较大的时空开销,因此需要引入轻型进程:二是由于对称多处理机(SMP)出现,可以满足多个运行单位,而多个进程并行开销过大. 因此在80年代,出现了能独立运行的基本单位--线程(Threads).        线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(P

  • c#.net多线程编程教学——线程同步

    随着对多线程学习的深入,你可能觉得需要了解一些有关线程共享资源的问题. .NET framework提供了很多的类和数据类型来控制对共享资源的访问. 考虑一种我们经常遇到的情况:有一些全局变量和共享的类变量,我们需要从不同的线程来更新它们,可以通过使用System.Threading.Interlocked类完成这样的任务,它提供了原子的,非模块化的整数更新操作. 还有你可以使用System.Threading.Monitor类锁定对象的方法的一段代码,使其暂时不能被别的线程访问. System

  • C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法

    本文实例讲述了C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法.分享给大家供大家参考,具体如下: 摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景.该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据. 使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的

  • C#简单多线程同步和优先权用法实例

    本文实例讲述了C#简单多线程同步和优先权用法.分享给大家供大家参考.具体分析如下: 本文实例题目如下: 麦当劳有两个做汉堡的厨师(工号:11,12)和三个销售人员(工号:21,22,23). 厨师生产汉堡,并负责将做好的汉堡放入货架,货架台大小有限,最多放6个汉堡,11和12不能同时往货架台上放汉堡,11具有优先权. 销售人员负责销售食品,三个销售人员取食品时,货架不能为空,三人不能同时取,23优先权最高,21最低.21卖的最快,取得频率最高,22次之. 一天的工作量是销售70个汉堡. 这里先来

  • 基于多线程中join()的用法实例讲解

    Thread中,join()方法的作用是调用线程等待该线程完成后,才能继续用下运行. public class TestThread5 { public static void main(String[] args) throws InterruptedException { Runner0 run5 = new Runner0(); Thread th5 = new Thread(run5); th5.start(); th5.join();//join()方法用在此处是为了等待主线程结束后运

  • python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 复制代码 代码如下: mutex = threading.Lock() #锁的使用 #创建锁 mutex = threading.Lock() #锁定 mutex.acquire([timeout]) #释放 mutex.release() 锁定方法acquire可以有一个超时时间的可选参数timeout.如果设定了timeout,则在超时后通过返回值

  • python简单的函数定义和用法实例

    本文实例讲述了python简单的函数定义和用法.分享给大家供大家参考.具体分析如下: 这里定义了一个温度转换的函数及其用法. def convertTemp(temp, scale): if scale == "c": return (temp - 32.0) * (5.0/9.0) elif scale == "f": return temp * 9.0/5.0 + 32 temp = int(input("Enter a temperature: &q

  • C#中简单的拆箱操作用法实例分析

    本文实例讲述了C#中简单的拆箱操作用法.分享给大家供大家参考.具体如下: C#中拆箱是允许将引用作为值类型的进行处理的过程.下面这段代码实现将object转换成int类型 using System; class ConversionSample { static void Main() { Object obj = 123; int num1 = (int)obj; Console.WriteLine(num1.ToString()); Console.WriteLine(obj.ToStrin

  • Java简单工厂模式定义与用法实例分析

    本文实例讲述了Java简单工厂模式定义与用法.分享给大家供大家参考,具体如下: 一 代码 // 抽象产品(Abstract Product)角色 interface Block { public void print(); } // 具体产品角色 class IBlock implements Block { public void print() { System.out.println("我是一个I形的方块!"); } } // 具体产品角色 class LBlock implem

  • Python多线程通信queue队列用法实例分析

    本文实例讲述了Python多线程通信queue队列用法.分享给大家供大家参考,具体如下: queue: 什么是队列:是一种特殊的结构,类似于列表.不过就像排队一样,队列中的元素一旦取出,那么就会从队列中删除. 线程之间的通信可以使用队列queue来进行 线程如何使用queue.Queue[还有其他类型的对象下面讲]来通信: 1.创建一个Queue对象:对象=queue.Queue(x),x是队列容量,x可以不填,默认没有容量限制, 2.get()可以使线程从队列中获取一个元素,如果队列为空,ge

  • Java中CountDownLatch进行多线程同步详解及实例代码

    Java中CountDownLatch进行多线程同步详解 CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantLock.ReadWriteLock锁实现同步. 3.信号量Semaphore实现同步. 其中,synchronized关键字和Lock锁解决的是多个线程对同一资源的并发访问问题.信号量Semaphore解决的是多副本资源的共享访问问题. 今天

  • Java多线程编程之Lock用法实例

    锁是控制多个线程对共享资源进行访问的工具.通常,锁提供了对共享资源的独占访问.一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁.不过,某些锁可能允许对共享资源并发访问,如 ReadWriteLock(维护了一对相关的锁,一个用于只读操作,另一个用于写入操作) 的读写锁. 1.Lock提供了无条件的.可轮询的.定时的.可中断的锁获取操作,所有加锁和解锁的方法都是显式的. public interface Lock{ void lock(); //加锁 //优先考虑响应中断,而不是响应

  • php多线程实现方法及用法实例详解

    下面我们来介绍具体php多线程实现程序代码,有需要了解的同学可参考. 当有人想要实现并发功能时,他们通常会想到用fork或者spawn threads,但是当他们发现php不支持多线程的时候,大概会转换思路去用一些不够好的语言,比如perl. 其实的是大多数情况下,你大可不必使用fork 或者线程,并且你会得到比用fork 或thread 更好的性能. 假设你要建立一个服务来检查正在运行的n台服务器,以确定他们还在正常运转.你可能会写下面这样的代码: 代码如下 <?php $hosts = ar

随机推荐