最近在项目中使用多线程,但是对多线程的一些用法和概念还有有些模棱两可,为了搞清楚查阅了一写资料,写下这篇日志加深理解吧。

Thread.Join()在MSDN中的解释很模糊:Blocks the calling thread until a thread terminates

有两个主要问题:1.什么是the calling thread?

2.什么是a thread?

首先来看一下有关的概念: 我们执行一个.exe文件实际上就是开启了一个进程,同时开启了至少一个线程

但是真正干活的是线程,就好比一个Team有好几个人,但是真正干活的是人不是Team.

具体到代码来说,以控制台程序为例:程序Test.exe从Main函数开始运行,实际上是有一个线程

在执行Main函数,我们称作MainThread.假如我们在Main函数中声明了一个Thread,称作NewThread,并且调用了

NewThread.Start()的方法,那么 MainThread在处理Main函数里面的代码时遇到NewThread.Start()时,就会

去调用NewThread.

基于上面的讨论,我们可以得出结论:在我们刚才的例子中the calling thread就是MainThread,而a thread

指的洽洽就是MainThread调用的NewThread线程。

现在回到MSDN的解释,我们可以这么翻译:当NewThread调用Join方法的时候,MainThread就被停止执行,

直到NewThread线程执行完毕。这样就好理解了。

static void Main(string[] args)
{ Thread thread1 = new Thread(new ThreadStart(()=> { Thread.Sleep();
Console.WriteLine("我是新线程打印的!"); })); thread1.Start(); Console.WriteLine("我是主线程打印的!"); Console.Read(); }

在Main函数中开启一个新的线程执行NewFunc方法,在方法中先休息500毫秒然后打印一段标志语。虽然thread1.Start()先于主线程的打印语句,但是新线程休息了500毫秒,所以执行结果应该是:

从结果中可以看到,先执行的主线程,然后执行的新线程,如果我们想让新线程执行完毕后再继续执行主线程呢?这时就用到了Thread.Join(),我们在thread1.Start()后面添加thread1.Join(),这样就会先执行完新线程后再去执行主线程。

static void Main(string[] args)
{ Thread thread1 = new Thread(new ThreadStart(()=> { Thread.Sleep();
Console.WriteLine("我是新线程打印的!"); })); thread1.Start();
thread1.Join(); Console.WriteLine("我是主线程打印的!"); Console.Read(); }

这段代码执行的结果为:

这次打印的结果和没加thread1.Join()的输出结果刚好相反。

到此我们可以得出结论,当调用Thread.Join()后,主线程是被阻塞了的,直到新线程执行完毕才继续执行,这是可以肯定的,可是我们目前只开了一个线程,如果在开一个线程会怎么样呢?我们接着测试:

static void Main(string[] args)
{ Thread thread1 = new Thread(new ThreadStart(()=> { for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine("我是第1个线程打印的!");
} })); Thread thread2 = new Thread(new ThreadStart(() => { for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine("我是第2个线程1打印的!");
} })); thread2.Start();
thread1.Start(); thread2.Join();
thread1.Join(); Console.WriteLine("我是主线程打印的!"); Console.Read(); }

输出结果为:

虽然第二个线程在第一个线程刚刚启动后就调用了Join()但是并没有阻塞第一个线程的执行,由此可以验证the calling thread,应为第二个线程是由主线程开启的,所以只能阻塞主线程,而不能阻塞其他线程,下面再接着实验在线程中再开一个新的线程:

static void Main(string[] args)
{ Thread thread1 = new Thread(new ThreadStart(()=> { Thread thread11 = new Thread(new ThreadStart(() => { for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine("我是第1-1个线程1打印的!");
} })); thread11.Start(); for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine("我是第1个线程打印的!");
} })); thread1.Start(); Console.WriteLine("我是主线程打印的!"); Console.Read(); }

改代码的执行结果是:

thread1和thread11是同步执行的,由于thread11是由thread1开启的,下面调用thread11在看看结果:

static void Main(string[] args)
{ Thread thread1 = new Thread(new ThreadStart(()=> { Thread thread11 = new Thread(new ThreadStart(() => { for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine("我是第1-1个线程1打印的!");
} })); thread11.Start();
thread11.Join(); for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine("我是第1个线程打印的!");
} })); thread1.Start(); Console.WriteLine("我是主线程打印的!"); Console.Read();
}

改代码的执行结果为:

由此可见,thread11.Join()方法是阻塞了thread1的,并没有阻塞主线程。再一次验证the calling thread指的是开启新线程的那个线程,而不一定是主线程。

此外,Thread.Join()还有两个重载方法:

public bool Join(TimeSpan timeout);

public bool Join(int millisecondsTimeout);

两个方法的参数不一样但是效果是一样的,目的是阻塞the calling thread的一定的时间,如果过了这个时间子线程还没有执行完毕,那么the calling thread就会接着执行。例如:我中午叫个同事一起去吃饭,但是他手头还有点工作磨磨唧唧的一直没有做完,如果是Join()的话我就一直等着,直到他做完我俩一起去吃饭,而Join(TimeSpan timeout)和Join(int millisecondsTimeout)就是,你Y快点啊,我在等你几分钟,你在默默唧唧干不完我就不等你了,我先去了。

最新文章

  1. 【Oracle】oracle中rownum的说明及使用技巧
  2. 两个七牛app上传小脚本
  3. SPL--Serializable
  4. Yii2.0高级框架数据库增删改查的一些操作(转)
  5. 翻译-In-Stream Big Data Processing 流式大数据处理
  6. java多线程(一)——线程安全的单例模式
  7. 开源分布式实时计算引擎 Iveely Computing 之 WordCount 详解(3)
  8. Linux中JDK环境变量的配置
  9. RAC SCAN
  10. SVN更改登录用户(转)
  11. [C++学习历程]基础部分 C++中的指针数组和结构
  12. 20190323——HeadFirestPython学习之异常处理
  13. [转帖]再次提醒Google Chrome用户应尽快升级浏览器到72.0.3626.121
  14. makefile——小试牛刀
  15. JavaScript 经典笔记
  16. 【delphi】TStringList类常用属性方法详解
  17. BIOS、MBR、UEFI和GPT关系
  18. AndroidWear开发之下载SDK[Android W/Android L]
  19. AngularJS SQL
  20. 迷你MVVM框架 avalonjs 0.84发布

热门文章

  1. node.js + socket.io实现聊天室一
  2. lnmp安装fileinfo扩展
  3. python中 and 和 or 运算的核心思想 ——— 短路逻辑
  4. Choose the best route--hdu2680
  5. Codeforces Round #277 (Div. 2) 解题报告
  6. 浅谈WebView的使用 js alert
  7. Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom(转)
  8. 【转】 Ubuntu下配置USB转串口及串口工具配置--不错
  9. 在wp中,使用NavigationService.Navigate导航页面出现错误
  10. HDU 1074 Doing Homework (状态压缩 DP)