.NET多线程-基本概念

1. 什么是多线程

线程是操作系统中能够独立运行的最小单位,也是程序中能够并发执行的一段指令序列

线程是进程的一部分,一个进程可以包含多个线程,这些线程共享进程的资源

进程有入口线程,也可以创建更多的线程

比如我们写了一个控制台程序,运行之后这个程序就会变成一个进程,同时入口函数所在的线程就是主线程或者入口线程

2.为什么需要多线程技术
应用场景:

批量重复任务希望同时进行(比如对于数组中打每个元素都进行相同且耗时打操作)

多个不同任务希望同时进行,互不干扰(比如有多个后台线程需要做轮询等操作)

比如WPF UI线程为主线程,但你需要执行一个很繁重的IO操作,就可以使用多线程实现

3. 什么是线程池

一组预先创建的线程,可以被重复使用来执行多个任务

避免频繁地创建和销毁线程,从而减少了线程创建和销毁的开销,提高了系统的性能和效率(生命周期

异步编程默认使用线程池(一般我们使用异步编程而很少和线程池打交道

4. 什么是线程安全
线程安全

多个线程访问共享资源时,对共享线程的访问不会导致数据不一致或不可预期的后果

解决方案:
同步机制

用于协调和控制多个线程之间执行顺序和互斥访问共享资源

确保线程按照特定的顺序执行,避免竞态条件和数据不一致的问题

原子操作

在执行过程中不会被中断的操作。不可分割,要么完全执行,要么完全不执行,没有中间状态

在多线程环境下,原子操作能够保证数据的一致性和可靠性,避免竞态条件和数据竞争的问题

C#
const int total = 10_0000;
int count = 0;
object lockobj = new object();
var t1 = new Thread(TheardMethod);
var t2 = new Thread(TheardMethod);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine($"总数为:{count}");
void TheardMethod()
{
	for (int i = 0; i < total; i++)
	{
		//锁
		lock (lockobj)
		{
            count++;
        }
		
	}
}
C#
//队列线程不安全(不是原子操作,多个线程同时访问出现问题
var queue = new Queue<int>();
object lockobj = new object();
var produce = new Thread(AddNum);
var conso1 = new Thread(ReadNum);
var conso2 = new Thread(ReadNum);

produce.Start();
conso1.Start();
conso2.Start();
produce.Join();
conso1.Join();
conso2.Join();
conso1.Interrupt();
conso2.Interrupt();


void AddNum()
{
    for (int i = 0; i < 20; i++)
    {
        Thread.Sleep(20);
        queue.Enqueue(i);
    }

}

void ReadNum()
{
    try
    {
        while (true)
        {
            lock (lockobj)
            {
                if (queue.TryDequeue(out var res))
                {
                    Console.WriteLine(res);
                    Thread.Sleep(1);
                }
            }
        }
    }
    catch (ThreadInterruptedException ex)
    {
        Console.WriteLine(ex);
    }
}
实现原子操作
C#
const int total = 10_0000;
int count = 0;
var t1 = new Thread(TheardMethod);
var t2 = new Thread(TheardMethod);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine($"总数为:{count}");
void TheardMethod()
{
    for (int i = 0; i < total; i++)
    {


        Interlocked.Increment(ref count);

    }
}

实现线程安全避免数据不一致的问题

5. 常用的线程实现方法
  • 线程
  • 线程池
  • 异步编程
  • 自带方法:①parallel–For、ForEach、Invoke ②(并行LINQ)PLINQ — AsParallel、AsSequential,–AsOrderred
订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
滚动至顶部