C#中Thread.Join()的理解

时间:2023-02-22 17:09:30

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

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毫秒,所以执行结果应该是:

C#中Thread.Join()的理解

从结果中可以看到,先执行的主线程,然后执行的新线程,如果我们想让新线程执行完毕后再继续执行主线程呢?这时就用到了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(); }

这段代码执行的结果为:

C#中Thread.Join()的理解

这次打印的结果和没加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(); }

输出结果为:

C#中Thread.Join()的理解

虽然第二个线程在第一个线程刚刚启动后就调用了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(); }

改代码的执行结果是:

C#中Thread.Join()的理解

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();
}

改代码的执行结果为:

C#中Thread.Join()的理解

由此可见,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快点啊,我在等你几分钟,你在默默唧唧干不完我就不等你了,我先去了。

C#中Thread.Join()的理解的更多相关文章

  1. 关于C&num;中Thread&period;Join&lpar;&rpar;的一点理解

    原文地址:http://www.cnblogs.com/slikyn/articles/1525940.html 今天是第一次在C#中接触Thread,自己研究了一下其中Thread.Join()这个 ...

  2. 多线程编程&lpar;一&rpar; - 关于C&num;中Thread&period;Join&lpar;&rpar;

    Thread.Join()在MSDN中的解释很模糊:Blocks the calling thread until a thread terminates 有两个主要问题:1.什么是the calli ...

  3. C&num; 中Join&lpar; &rpar;的理解

    在MSDN中对Join( )的解释比较模糊:在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程(线程A),直到某个线程终(线程B)止为止. 首先来看一下有关的概念: 我 ...

  4. python中thread的setDaemon、join的用法的代码

    下面内容是关于python中thread的setDaemon.join的用法的内容. #! /usr/bin/env python import threading import time class ...

  5. python threading模块中的join&lpar;&rpar;方法和setDeamon&lpar;&rpar;方法的一些理解

    之前用多线程的时候看见了很多文章,比较常用的大概就是join()和setDeamon()了. 先说一下自己对join()的理解吧: def join(self, timeout=None): &quo ...

  6. Thread类中的join方法

    package charpter06; //类实现接口public class Processor implements Runnable { // 重写接口方法 @Override public v ...

  7. 【线程】Thread中的join介绍

    因为sleep.wait.join等阻塞,可以使用interrupted exception异常唤醒. 一.作用 Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行 ...

  8. Thread中,join()方法

    Thread中,join()方法的作用是调用线程等待该线程完成后,才能继续用下运行. public static void main(String[] args) throws Interrupted ...

  9. python多线程中join&lpar;&rpar;的理解

    在 Python 的多线程编程中,经常碰到 thread.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. 第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程 ...

随机推荐

  1. java如何在eclipse编译时自动生成代码

    用eclipse写java代码,自动编译时,如何能够触发一个动作,这个动作是生成本项目的代码,并且编译完成后,自动生成的代码也编译好了, java编辑器中就可以做到对新生成的代码的自动提示? 不生成代 ...

  2. fgets函数执行完成后,文件指针如何移动?

    用fgets执行之后,读取了文件中的一行,这时文件位置指针是自动指向文件的下一行的开头吗,还是指向当前行的结尾?如果一行的字符串没读取完会怎样? 实例结果: 如果一行的字符串没读取完会,下一次会接着上 ...

  3. 算法之旅,直奔&lt&semi;algorithm&gt&semi;之十七 find&lowbar;first&lowbar;of

    find_first_of(vs2010) 引言 这是我学习总结 <algorithm>的第十七篇,find_first_of是匹配的一个函数.<algorithm>是c++的 ...

  4. c&plus;&plus; 17介绍

    作者:hearts zh链接:https://www.zhihu.com/question/32222337/answer/55238928来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  5. Node&period;js学习系列1

    概述 最近在刷javascript的技能,觉着nodejs是个不错的入口,作为一个.Net平台的前端工程师学习使用js开发服务端,想想都有点小激动哈哈^_^^_^. 入门 之前开发过ionic,所以对 ...

  6. IE保护模式下ActiveX控件打不开共享内存的解决方案

    原文:http://www.cppblog.com/Streamlet/archive/2012/10/25/193831.html 感谢溪流漫话的投递 IE保护模式下,ActiveX控件会打不开别的 ...

  7. Ironic中pxe driver和agent driver的区别

    历史问题: 以pxe_ipmitool 和agent_ipmitool为例,看起来似乎前者不使用ironic-python-agent,后者使用,但是实际上两者都使用ironic-python-age ...

  8. Android重绘ListView高度

    Android重绘ListView高度 经常会有这样需求,需要ListView默认将所有的条目显示出来,这就需要外层使用ScrollView,ScrollView里面放置一个重绘高度的ListView ...

  9. Go源码编译安装

    参考文档1:https://www.cnblogs.com/majianguo/p/7258975.html 参考文档2:http://www.loongson.cn/news/company/456 ...

  10. vue初体验

    作为一个前端的小菜鸟,在平时的开发与学习中,除了要深入了解javascript 及 css 的各种特性,熟悉一门框架也是必不可少的.vue以其小巧,轻便,学习平滑等各种特性深受欢迎. 这里总结一下小菜 ...