在 C#
中,多线程编程是一项重要技能,它允许程序同时执行多个任务,提高应用的并发能力和效率。在多线程编程中,有许多类和方法可供使用。常用的多线程类主要分为以下几大类:线程管理类、并行库类、同步类、并发集合等。
目录
1. 基础多线程类
System.Threading
命名空间中的类是 C#
多线程编程的基础。主要用于创建和管理线程。
1.1 Thread
Thread
是基础的多线程类,表示一个独立的执行路径。开发者可以使用 Thread
创建并启动线程。
使用示例
using System;
using System.Threading;
class Program
{
static void Main()
{
// 创建并启动新线程
Thread thread = new Thread(DoWork);
thread.Start();
// 主线程继续执行
Console.WriteLine("Main thread running...");
}
static void DoWork()
{
Console.WriteLine("Work is being done in a separate thread.");
}
}
Thread.Start()
:启动线程,在线程中执行指定的操作。Thread.Join()
:阻塞调用线程,直到目标线程完成。Thread.Sleep()
:暂停当前线程一段时间。
1.2 ParameterizedThreadStart
当需要在线程中传递参数时,可以使用 ParameterizedThreadStart
。
Thread thread = new Thread(new ParameterizedThreadStart(DoWorkWithParam));
thread.Start("Hello from thread!");
static void DoWorkWithParam(object param)
{
Console.WriteLine(param);
}
2. 任务并行库 (Task Parallel Library, TPL)
Task
并行库是多线程的高级抽象,它比 Thread
更灵活,能够更好地处理复杂的并发任务。Task
是基于线程池的,更适合处理短时间的并发任务。
2.1 Task
Task
类表示一个异步操作。通过 Task
,可以启动、取消和等待任务。
使用示例
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// 创建并启动一个任务
Task task = Task.Run(() => DoWork());
task.Wait(); // 等待任务完成
Console.WriteLine("Task completed.");
}
static void DoWork()
{
Console.WriteLine("Work is being done in a Task.");
}
}
Task.Run()
:创建并启动一个新任务。Task.Wait()
:等待任务完成。Task.Result
:获取任务的结果(适用于返回值任务)。
2.2 Task<TResult>
Task<TResult>
是 Task
的泛型版本,允许任务返回结果。
使用示例
Task<int> task = Task.Run(() => ComputeValue());
Console.WriteLine(task.Result); // 获取任务返回值
static int ComputeValue()
{
return 42;
}
2.3 async
/await
async
和 await
是用于异步编程的关键字,结合 Task
使用能够简化异步操作。
static async Task Main(string[] args)
{
int result = await ComputeValueAsync();
Console.WriteLine(result);
}
static async Task<int> ComputeValueAsync()
{
await Task.Delay(1000); // 模拟异步操作
return 42;
}
3. 同步机制类
同步机制用于防止多线程同时访问共享资源,避免出现竞态条件和数据不一致的问题。
3.1 lock
lock
是 C#
中最常用的同步机制,用于锁定一个对象,确保同一时间只有一个线程可以访问锁定的代码块。
使用示例
private static readonly object _lock = new object();
static void DoWork()
{
lock (_lock)
{
// 同一时间只有一个线程可以执行此代码块
Console.WriteLine("Thread-safe work is being done.");
}
}
3.2 Monitor
Monitor
是 lock
的底层实现,提供更高级的锁定功能,例如尝试进入锁定和超时功能。
使用示例
Monitor.Enter(_lock);
try
{
// 线程安全操作
}
finally
{
Monitor.Exit(_lock);
}
3.3 Mutex
Mutex
(互斥体)用于跨进程的线程同步,确保系统中只有一个线程可以访问某个资源。
使用示例
Mutex mutex = new Mutex();
if (mutex.WaitOne())
{
try
{
// 线程安全操作
}
finally
{
mutex.ReleaseMutex();
}
}
3.4 Semaphore
和 SemaphoreSlim
Semaphore
用于限制同时访问资源的线程数。例如,允许 3 个线程同时访问某个资源。
使用示例
SemaphoreSlim semaphore = new SemaphoreSlim(3);
semaphore.Wait();
try
{
// 线程安全操作
}
finally
{
semaphore.Release();
}
4. 并发集合类
并发集合是线程安全的集合类,允许多个线程同时读取和写入数据,而不会出现数据冲突。
4.1 ConcurrentDictionary
ConcurrentDictionary
是线程安全的键值对集合,支持并发读写操作。
使用示例
using System.Collections.Concurrent;
ConcurrentDictionary<int, string> dict = new ConcurrentDictionary<int, string>();
dict.TryAdd(1, "One");
Console.WriteLine(dict[1]); // 输出 "One"
4.2 ConcurrentQueue
ConcurrentQueue
是线程安全的队列,支持多个线程安全地读取和写入数据。
使用示例
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
queue.Enqueue(1);
queue.TryDequeue(out int result);
Console.WriteLine(result); // 输出 "1"
4.3 BlockingCollection
BlockingCollection
是一个线程安全的集合,支持生产者-消费者模式。
使用示例
BlockingCollection<int> collection = new BlockingCollection<int>();
Task producer = Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
collection.Add(i);
}
collection.CompleteAdding();
});
Task consumer = Task.Run(() =>
{
foreach (var item in collection.GetConsumingEnumerable())
{
Console.WriteLine(item);
}
});
Task.WaitAll(producer, consumer);
5. 线程安全类
5.1 Interlocked
Interlocked
提供了原子操作,可以确保多个线程在对某些变量(如计数器)进行操作时,不会发生数据冲突。
使用示例
int counter = 0;
Interlocked.Increment(ref counter); // 线程安全的递增操作
Console.WriteLine(counter);
6. 线程池
6.1 ThreadPool
ThreadPool
是一种管理和重用线程的机制。通过 ThreadPool
,可以将任务提交给线程池中的线程执行,而无需显式管理线程的生命周期。
使用示例
ThreadPool.QueueUserWorkItem(DoWork);
static void DoWork(object state)
{
Console.WriteLine("Task running in thread pool.");
}
6.2 Task.Run
与 ThreadPool
Task.Run
也是基于线程池的,因此可以通过 Task.Run
创建并行任务,并在内部复用线程池。
Task.Run(() => DoWork());
7. 总结
C#
中的多线程编程提供了丰富的类库和工具,帮助开发者轻松管理并发任务和线程安全问题。从低级的 Thread
到高级的 Task
并行库,再到同步机制和并发集合,开发者可以根据不同的需求选择合适的多线程工具。熟练掌握这些类和工具能够显著提高应用程序的并发性能,避免竞态条件和死锁等常见问题。