📜  c# 新线程 - C# (1)

📅  最后修改于: 2023-12-03 15:13:51.846000             🧑  作者: Mango

C# 新线程

在C#中,线程(Thread)是一种轻量级的执行单元,它允许程序的多个部分同时执行。在一些需要实现同时执行任务的场景中,线程可以提高程序的执行效率。

创建新线程

C#中创建新线程有两种方式:

使用Thread类

使用Thread类创建新线程,可以通过初始化Thread类实例并传递线程入口方法来实现。下面是一个简单的示例:

using System;
using System.Threading;

public class Program
{
    public static void Main(string[] args)
    {
        Thread t = new Thread(DoWork);
        t.Start();
    }

    private static void DoWork()
    {
        // 线程执行的方法
    }
}

在上面的代码中,我们创建了一个新的线程t,并将一个名为DoWork的方法作为线程的入口方法。t.Start()方法用于启动线程。

使用Task类

Task类是.NET Framework 4.0中引入的一种方式,用于对线程进行抽象。Task类的使用是在Thread类的基础上进行改进的,其优点是可以更加方便地使用并行编程。下面是一个简单的示例:

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main(string[] args)
    {
        Task.Run(() => DoWork());
    }

    private static void DoWork()
    {
        // 线程执行的方法
    }
}

在上面的代码中,我们使用Task类的静态方法Run来创建一个新的Task并启动线程。DoWork方法同样是线程的入口方法。

线程同步

在多线程程序中,线程之间可能存在数据同时操作的问题,为了防止出现这种问题,C#中提供了多种同步机制。

lock关键字

lock关键字用于保护临界区,确保同一时刻只能有一个线程访问临界区。下面是一个简单的示例:

using System;
using System.Threading;

public class Program
{
    private static object lockObj = new object();

    public static void Main(string[] args)
    {
        Thread t1 = new Thread(DoWork);
        Thread t2 = new Thread(DoWork);
        t1.Start();
        t2.Start();
    }

    private static void DoWork()
    {
        lock (lockObj)
        {
            // 线程执行的方法
        }
    }
}

在上面的代码中,我们使用lock关键字来保护了临界区。多个线程在访问临界区时,只有其中一个线程可以获得锁并执行临界区代码,其他线程则等待锁的释放。

Interlocked类

Interlocked类提供了多种线程安全的操作,包括自增、自减、比较交换等操作。下面是一个简单的示例:

using System.Threading;

public class Program
{
    private static int counter = 0;

    public static void Main(string[] args)
    {
        Thread t1 = new Thread(DoWork);
        Thread t2 = new Thread(DoWork);
        t1.Start();
        t2.Start();
        t1.Join();
        t2.Join();
        // 输出counter的值
        Console.WriteLine(counter);
    }

    private static void DoWork()
    {
        for (int i = 0; i < 1000000; i++)
        {
            Interlocked.Increment(ref counter);
        }
    }
}

在上面的代码中,我们使用Interlocked类的Increment方法来实现线程安全的自增操作。由于自增操作是一个常见的操作,因此Interlocked类提供了一种相对简单的方式来实现线程安全。在本例中,我们启动了两个线程来执行DoWork方法,在DoWork方法中执行1000000次的自增操作,并使用Interlocked.Increment来保证线程安全。

线程池

C#中提供了线程池功能,可以避免频繁创建和销毁线程所导致的性能损失。下面是一个简单的示例:

using System;
using System.Threading;

public class Program
{
    public static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            ThreadPool.QueueUserWorkItem(DoWork, i);
        }
        // 等待所有线程执行完
        ThreadPool.WaitAll();
    }

    private static void DoWork(object state)
    {
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is working with state {state}");
    }
}

在上面的代码中,我们使用了ThreadPool静态类来管理线程池。我们使用了QueueUserWorkItem方法将DoWork方法加入到线程池中,线程池会自动管理线程的数量和状态。在本例中,我们将DoWork方法加入了10次,每次传递一个不同的state值,ThreadPool会自动分配线程,运行DoWork方法并传递对应的state值。最后,我们使用了WaitAll方法等待所有线程都执行完。

总结

本文介绍了在C#中创建新线程、同步机制以及线程池的使用。通过本文的介绍,相信读者已经掌握了基本的多线程编程知识。当然,多线程编程是一门广阔而深入的技术,对于一些复杂的并发场景,需要进一步深入学习。