热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

多线程基础概览

本文探讨了多线程的起源及其在现代编程中的重要性。线程的引入是为了增强进程的稳定性,确保一个进程的崩溃不会影响其他进程。而进程的存在则是为了保障操作系统的稳定运行,防止单一应用程序的错误导致整个系统的崩溃。线程作为进程的逻辑单元,多个线程共享同一CPU,需要合理调度以避免资源竞争。

线程和进程的概念源于对系统稳定性的追求。线程是为了提高进程的稳定性而设计的,一个进程的崩溃不应影响其他进程的正常运行。同样,进程的存在是为了保护操作系统的稳定性,避免一个应用程序的错误导致整个系统的崩溃。

线程是进程的逻辑单元,多个线程可以共享同一个CPU,但这也带来了资源竞争的问题。为了确保数据的一致性,操作系统会定期对线程进行调度,通常每30毫秒进行一次切换。虽然这种切换会带来一定的性能开销,但在多核处理器时代,这点性能损耗是可以接受的。

在.NET框架中,线程的实现主要通过Thread类来完成,分为前台线程和后台线程,通过IsBackground属性进行标记。通常情况下,我们更倾向于使用后台线程,即异步线程。线程具有优先级,高优先级的线程在调度时会被优先处理。.NET提供了丰富的线程API,如SleepJoinAbort等。

线程池的引入旨在解决频繁创建和销毁线程带来的性能问题。线程池通过复用线程来减少这些开销。当一个线程完成任务后,它会返回线程池,等待下一次调用。例如,一个线程池中有5个线程,处理1000条数据时,每个线程可以处理200条数据。尽管线程池提高了性能,但也存在一些不足,如无法实时查看线程进度和反馈执行结果。为了解决这些问题,.NET引入了Task类,它是在线程池基础上的进一步封装和优化,提供了更多的API,如RunStartFactoryWaitWaitAllContinueWith等。

下面是一个简单的单线程示例:

/// 
/// 单线程应用
/// 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("进入主线程");
        User u = new User("小刚");
        u.Getshow();
        Console.WriteLine("主线程结束");
    }
}

public class User
{
    private string name;
    public User(string name)
    {
        this.name = name;
    }
    public void Getshow()
    {
        Console.WriteLine("Name=>" + name);
    }
}

在这个控制台程序中,只有一个由系统自动分配的主线程。程序从Main方法开始执行,顺序控制流程。当执行到GetShow方法时,线程会进入该方法内部执行,完成后返回Main方法继续执行后续代码。

接下来,我们通过创建一个新的线程来执行GetShow方法:

/// 
/// 多线程应用
/// 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("进入主线程");
        User u = new User("小刚");
        Thread subthread = new Thread(new ThreadStart(u.Getshow)); // 创建新线程
        subthread.Start(); // 开启线程
        Console.WriteLine("主线程结束");
    }
}

public class User
{
    private string name;
    public User(string name)
    {
        this.name = name;
    }
    public void Getshow()
    {
        Console.WriteLine("Name=>" + name);
    }
}

在主线程中,我们创建了一个新的线程来执行GetShow方法。主线程不会等待新线程完成任务,而是继续执行后续代码。这意味着主线程和新线程可以并行执行,但谁先完成是不确定的。


推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 探讨如何通过编程技术实现100个并发连接,解决线程创建顺序问题,并提供高效的并发测试方案。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文介绍了如何在C#中启动一个应用程序,并通过枚举窗口来获取其主窗口句柄。当使用Process类启动程序时,我们通常只能获得进程的句柄,而主窗口句柄可能为0。因此,我们需要使用API函数和回调机制来准确获取主窗口句柄。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
  • 本文详细介绍了Java中的访问器(getter)和修改器(setter),探讨了它们在保护数据完整性、增强代码可维护性方面的重要作用。通过具体示例,展示了如何正确使用这些方法来控制类属性的访问和更新。 ... [详细]
  • 如何在窗口右下角添加调整大小的手柄
    本文探讨了如何在传统MFC/Win32 API编程中实现类似C# WinForms中的SizeGrip功能,即在窗口的右下角显示一个用于调整窗口大小的手柄。我们将介绍具体的实现方法和相关API。 ... [详细]
author-avatar
何其何从丶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有