自学内容网 自学内容网

C# 多线程 学习理解记录

学习抖音AI先锋的讲解视频

主线程之外可以开启现场运行,而不影响主线程,

比如开启线程任务后不影响窗口拖拽

Task 和 Thread对比

Thread th=new Thread(函数名称或匿名函数);

Task.run(函数名称或匿名函数);

底层一样,但是Task封装得更好,更容易管理

比如:

等待单个线程任务:

在异步方法 的函数体里 await  Task.run(函数名称或匿名函数);,会等待现场运行完该行代码

等待多个线程任务:

List<Task> ts=new List<Task>();    add()函数装多个任务·

然后

Task.WhenAll(ts).ContinueWith(完成前面列表任务后执行的函数):

=====================================

学习siki学院 siki老师 的视频

4 02视频   Thread启动线程和数据传输

#region Theard多线程传输数据
public struct MyData
{
public string message; 
public int age;
}
public void DownloadStr(Object o)
{
if (o == null) return;
string str = o as string;//转换异常为null
Console.WriteLine($"str:{str}");
}
public void DownloadMyData(Object o)
{
if (o is MyData&&!o.Equals(null))
{
MyData data = (MyData)o;//结构体是值类型,不能使用null赋值,故不能使用o as MyData转换
Console.WriteLine($"message:{data.message},age:{data.age}");
}
}
public void Theard()
{
Thread thread1 = new Thread(DownloadStr);
thread1.Start("thread1 参数");

Thread thread2 = new Thread(DownloadMyData);
MyData thisData = new MyData() { message="message",age=12};
thread2.Start(thisData);
}
#endregion

403 前台线程和 后台线程

前台线程 Main线程,和Thread 初始化属性isBackground =false; 为前台线程

当前台线程都关闭时,会不等待后台线程,开始尝试关闭程序进程(有一定的关闭时间)

404 线程优先级和线程状态

单个CPU 分别执行不同线程的任务,速度极快,人的感觉就像同时执行而已

那么他们就有调度规则,

线程的优先级线程有操作系统调度,一个CPU同一时间只能做一件事情(运行一个线程中的计算任务),当有很多线程需要CPU去执行的时候,线程调度器会根据线程的优先级去判断先去执行哪一个线程,如果优先级相同的话,就使用一个循环调度规则,逐个执行每个线程。在Thead类中,可以设置Priority属性,以影响线程的基本优先级,Priority属性是一个ThreadPriority枚举定义的一个值。定义的级别有Highest,AboveNormal,Normal,BelowNormal 和 Lowest

实践测试,当都是默认的主线程(Normal级别)创建的线程也是默认同一级别,分配到的执行时间也差不多,优先级高不一定被执行得更多,但抢占的时间会长一点,多个CPU,系统会尽量分配到不同CPU上

static void A()

{

        while (true){

                Console.Write("A");

        // 输出线程信息和当前CPU核心

        int threadId = Thread.CurrentThread.ManagedThreadId;
int processorId = GetCurrentProcessorNumber();
Console.WriteLine($"线程ID: {threadId}, 运行的CPU核心ID: {processorId}");

        }

}

static void B()

{

        while (true){

                Console.Write("B");

        // 输出线程信息和当前CPU核心

        int threadId = Thread.CurrentThread.ManagedThreadId;
int processorId = GetCurrentProcessorNumber();
Console.WriteLine($"线程ID: {threadId}, 运行的CPU核心ID: {processorId}");

        }

}

static void Main(string[] args)

{

        Thread a = new Thread(A);

        Thread b = new Thread(B);

        a.Priority = ThreadPriority.AboveNormal;

        a.Start();

        b.Start();

}

 b.Join();  线程和主线程合二为一 

405线程池

系统自带的ThreadPool

线程池中的所有线程都是后台线程。如果进程的所有前台线程都结束了,所有的后台线程就会停不能把入池的线程改为前台线程。

一般都是放一些短时任务,以防在程序结束前没运行完成

406多线程之任务Task

System.Threading.Tasks

启动任务启动任务的三种方式:

TaskFactory tf = new TaskFactory();

Task t1 = tf. StartNew(TaskMethod);

Task t2 = TaskFactory.StartNew(TaskMethod);

Task t3 = new Task(TaskMethod);t3. Start();

是放到线程池的后台任务,前台任务消失后退出程序

407多线程之 资源访问冲突问题

private int state = 5;

public void ChangeState()

{

        if (state = 5)

        {

                state++;

                Console.Writeline("State :"+ state +":"+Thread.CurrentThread.ManagedThreadId);

        }

        state = 5;

}

public void Test()

{

        for(int i = 0; i < 100; i++)

        {

                Thread t = new Thread(ChangeState);

        }

        t.Start();

}

//有些线程输出打印数据时,有些线程刚刚好设置回5,导致数据异常

//解决方法时创建一个锁,可以是任意对象并不能为null,一般Object对象

408 死锁的问题

一个锁锁单个资源或多个资源,但锁住了,下一个要使用的线程就卡柱了 。

死锁场景:

比如资源1 和资源2,线程1的使用顺序时 资源1》资源2,线程2的使用顺序时 资源2》资源1,

很可能两个线程都卡柱


原文地址:https://blog.csdn.net/qq_38239133/article/details/144583468

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!