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

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

在C#中,多线程编程可以提高CPU利用率,提高程序的响应速度,增强程序的稳定性。但多线程编程中也会遇到诸多问题,比如线程安全、死锁、优先级等问题,需要进行同步和协同操作。本文将从多线程编程和同步操作两个方面进行简要分析,并提供两个实例来加深读者的理解。

多线程编程示例

示例一:简单的启动线程和等待线程结束

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(Worker);
        thread.Start();
        Console.WriteLine("主线程开始等待工作线程结束");
        thread.Join();
        Console.WriteLine("工作线程已结束");
    }

    static void Worker()
    {
        Console.WriteLine("工作线程正在工作...");
        Thread.Sleep(5000); // 模拟一些工作
        Console.WriteLine("工作线程已结束");
    }
}

上述示例中,通过创建Worker方法的线程,来模拟一些耗时的工作,而主线程则在启动此线程之后,等待线程结束,再继续执行代码。

示例二:线程安全的计数器

using System;
using System.Threading;

class Program
{
    static volatile int count = 0; // volatile确保写操作的可见性

    static void Main(string[] args)
    {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.Length; i++)
        {
            threads[i] = new Thread(Worker);
            threads[i].Start();
        }
        foreach (Thread thread in threads) thread.Join(); // 等待所有线程结束
        Console.WriteLine("计数器结果: " + count);
    }

    static void Worker()
    {
        for (int i = 0; i < 100000; i++) Interlocked.Increment(ref count); // 加锁保证访问安全
    }
}

上述示例中,创建10个线程,每个线程都会执行100000次的计数操作。由于多个线程可能会同时对计数器进行修改,会导致数据不一致或者程序崩溃等问题。因此,在每次修改计数器时,需要使用加锁保证访问的安全性。同时使用volatile关键字,确保写操作的可见性。

同步示例

示例一:互斥锁

using System;
using System.Threading;

class Program
{
    static bool stop = false;
    static Mutex mutex = new Mutex();

    static void Main(string[] args)
    {
        Thread thread1 = new Thread(Worker1);
        Thread thread2 = new Thread(Worker2);
        thread1.Start();
        thread2.Start();
        Console.ReadKey();
        stop = true;
    }

    static void Worker1()
    {
        while (!stop)
        {
            mutex.WaitOne();
            Console.WriteLine("Worker1正在工作...");
            Thread.Sleep(100);
            mutex.ReleaseMutex();
        }
        Console.WriteLine("Worker1已停止");
    }

    static void Worker2()
    {
        while (!stop)
        {
            mutex.WaitOne();
            Console.WriteLine("Worker2正在工作...");
            Thread.Sleep(200);
            mutex.ReleaseMutex();
        }
        Console.WriteLine("Worker2已停止");
    }
}

上述示例中,使用Mutex类来创建一个互斥锁,确保同一时刻只有一个线程能够访问共享资源。Worker1和Worker2线程会多次等待互斥锁,并分别对共享资源进行访问。

示例二:信号量

using System;
using System.Threading;

class Program
{
    static Semaphore sem = new Semaphore(2, 2); // 初始信号量为2,最大信号量为2

    static void Main(string[] args)
    {
        for (int i = 1; i <= 5; i++)
        {
            Thread thread = new Thread(Worker);
            thread.Name = "Worker" + i;
            thread.Start();
        }
        Console.ReadKey();
    }

    static void Worker()
    {
        Console.WriteLine(Thread.CurrentThread.Name + "等待信号量");
        sem.WaitOne(); //等待信号量
        Console.WriteLine(Thread.CurrentThread.Name + "开始工作");
        Thread.Sleep(2000);
        Console.WriteLine(Thread.CurrentThread.Name + "结束工作");
        sem.Release(); // 释放信号量
    }
}

上述示例中,使用Semaphore类来表示一个具有初始信号量的信号灯。多个Worker线程会在开始之前等待信号灯,只有在获得信号之后才能开始工作。在工作结束之后会释放信号灯。

总结

本文介绍了C#多线程编程和同步操作的相关知识,并提供了两个示例来帮助读者更好地理解。在实际应用中,多线程和同步操作需要结合具体业务场景进行设计和调整,以达到最优的效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#多线程及同步示例简析 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Python编程如何在递归函数中使用迭代器

    Python提供了一种在递归函数中使用迭代器的方法,即通过生成器实现。下面详细介绍如何实现和使用这种方法,并提供两个示例说明。 什么是生成器? 在开始介绍如何在递归函数中使用迭代器之前,我们需要先了解一下Python中的生成器。生成器是一种特殊的迭代器,它是使用yield语句来实现的。通过生成器,我们可以以惰性求值的方式逐步生成序列中的元素,而无需一次性将整…

    other 2023年6月27日
    00
  • SpringBoot读取自定义配置文件方式(properties,yaml)

    下面就详细讲解SpringBoot读取自定义配置文件的方式(properties,yaml)的完整攻略。 准备工作 在开始之前,需要先准备好SpringBoot项目并确保已经引入了spring-boot-starter相关依赖(如果是其他版本的依赖包,请自行查看对应的文档)。 读取properties配置文件 步骤 在项目的src/main/resource…

    other 2023年6月25日
    00
  • linux上安装zookeeper 启动和关闭的教程

    下面是详细的 “linux上安装zookeeper 启动和关闭的教程”。 安装Zookeeper 步骤一:下载Zookeeper 我们可以在Zookeeper官网或https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/下载所需版本的Zookeeper。这里我下载的是zookeeper-3.4.14.tar…

    other 2023年6月27日
    00
  • Symfony2学习笔记之插件格式分析

    Symfony2学习笔记之插件格式分析攻略 1. 简介 本攻略将详细讲解Symfony2插件格式分析的步骤和示例。Symfony2是一个流行的PHP框架,插件是扩展Symfony2功能的重要组成部分。 2. 插件格式分析步骤 下面是分析Symfony2插件格式的步骤: 步骤1:了解插件结构 首先,了解Symfony2插件的基本结构是很重要的。一个典型的Sym…

    other 2023年8月6日
    00
  • vue2封装input组件方式(输入的双向绑定)

    下面是我对于“vue2封装input组件方式(输入的双向绑定)”的完整攻略: 1. 前置知识 在深入介绍vue2封装input组件方式之前,需要先了解以下前置知识: 1.1 组件 在Vue中,组件是可复用的Vue实例,是页面的基本构成块。 1.2 双向绑定 Vue提供了双向绑定的功能,可以将数据的变化反映到视图中,也可以将视图的变化反映到数据中。 1.3 p…

    other 2023年6月25日
    00
  • druid0.17入门(3)——数据接入指南

    Druid是一款开源的分布式数据存储和分析系统,可以用于实时数据处理和分析。以下是Druid数据接入的基本步骤: 安装Druid 首先需要安装Druid,可以从官网下载安装包进行安装。 配置数据源 在Druid中,需要配置数据源,可以使用以下数据源: Kafka Hadoop JDBC S3 配置数据源的方法因数据源而异,可以参考Druid官方文档进行配置。…

    other 2023年5月5日
    00
  • 使用python爬取抖音app视频的实例代码

    以下是使用Python爬取抖音App视频的实例代码的完整攻略: 使用Python爬取抖音App视频的实例代码 1. 安装依赖库 首先,我们需要安装一些必要的依赖库,包括requests、json和re。可以使用以下命令来安装这些库: pip install requests pip install json pip install re 2. 获取抖音视频链…

    other 2023年10月14日
    00
  • 接口测试中模拟post四种请求数据

    接口测试中模拟POST四种请求数据 在接口测试中,POST请求是非常重要的一种请求类型,它通常用于向服务器提交数据,并根据提交的数据进行相关的操作,例如添加数据、修改数据、删除数据等等。 在进行POST请求测试时,我们需要模拟四种请求数据,分别是表单形式、JSON格式、XML格式和流媒体格式。接下来,我们将一一讲解。 1. 模拟表单形式数据 表单形式数据是一…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部