这俩例子是一样的,只是同一个东西的不同写法而已。
但是需要注意的是,每次运行的时候结果都是不一样的(需要多运行看结果 避免偶然性),因为当进入主函数的时候,就启动了主线程,然后当线程A启动之后启动线程B的时候,线程A未必结束了,而又因为CPU调度的原因,从而造成每次输出结果都不一样。具体原因见:https://blog.csdn.net/qq_43629857/article/details/114800940
但是代码二中因为有 Task.WaitAll 这个方法 ,所以最后的输出***还是在最后,不会像代码一样乱跑。这个注意一下就好。
Thread类几个重要方法:
-
Start():启动线程
-
Sleep(int):静态方法,暂停当前线程指定的毫秒数
-
Abort():通常使用该方法来终止一个线程
-
Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复
-
Resume():恢复被Suspend()方法挂起的线程的执行
-
Join():join的作用就是让输出变有序(看代码)。当调用了该方法后,当前线程会立即被执行
代码一
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Practice1
{
class Program
{
static void Main(string[] args)
{
Thread threadA=new Thread(delegate()
{
for(int i=0;i<10;i++)
Console.Write("A");
});
Thread threadB=new Thread(delegate()
{
for(int i=0;i<10;i++)
Console.Write("B");
//Console.Write("---");
threadA.Join();
for(int i=0;i<10;i++)
Console.Write("B");
});
threadA.Start();
threadB.Start();
Console.Write("*****"); // 也是乱序穿插在输出里面 因为这个时候上面的线程不一定结束了
}
}
}
代码二
项目上这样写多:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Practice1
{
class Program
{
static void Main(string[] args)
{
var t1= Task.Run(() => // Task.Run(async () =>
{
for (int i = 0; i < 5; i++)
Console.Write("A");
});
var t2= Task.Run(() =>
{
for (int i = 0; i < 5; i++)
Console.Write("B");
});
Task.WaitAll(t1,t2); // WaitAll等待所有线程执行完毕
Console.Write("*****"); // 这里输出和上面那个不一样,因为WaitAll方法是等所有线程执行完毕才执行的,上面那个不是
}
}
}
参考
https://www.cnblogs.com/Sweepingmonk/p/10868056.html
C#线程、线程池和Task关系:https://blog.csdn.net/u010476739/article/details/105346763/
主线程、子线程等的关系:https://blog.csdn.net/dq1005/article/details/50854550 主线程是前台进程,子线程是后台的意思?