bicabo C#多线程详解(三)
继续上一节的问题:调换两个新创建的线程启动顺序会是什么结果?
using System;
using System.Threading;
namespace Test
{
class TestThread
{
private static void FirstThreadFun()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(Thread.CurrentThread.Name + " i = " + i);
}
Console.WriteLine(Thread.CurrentThread.Name + "的优先级:" + Thread.CurrentThread.Priority);
Console.WriteLine(Thread.CurrentThread.Name + " 执行完毕");
}
private static void SecondThreadFun()
{
for (int j = 0; j < 10; j++)
{
Console.WriteLine(Thread.CurrentThread.Name + " j = " + j);
}
Console.WriteLine(Thread.CurrentThread.Name + "的优先级:" + Thread.CurrentThread.Priority);
Console.WriteLine(Thread.CurrentThread.Name + " 执行完毕");
}
static void Main(string[] args)
{
//程序调用了Main()函数时,就起动了一个进程,同时也启动了一个线程[这个线程就是主线程].
Thread.CurrentThread.Name = "MainThread";
Thread secondThread = new Thread(new ThreadStart(TestThread.SecondThreadFun));
//取名为 secondThread
secondThread.Name = "secondThread";
//设定线程的优先级为AboveNormal[在所有创建的新线程中,执行顺序为第二]
secondThread.Priority = ThreadPriority.AboveNormal;
//创建第一个线程
Thread firstThread = new Thread(new ThreadStart(TestThread.FirstThreadFun));
//取名为 firstThread
firstThread.Name = "firstThread";
//设定线程的优先级为最高级[在所有创建的新线程中,最先执行.线程优先级默认为Normal,共5 级:Highest,AboveNormal,Normal,BelowNormal,Lowest]
firstThread.Priority = ThreadPriority.Highest;
for (int z = 0; z < 20; z++)
{
if (z == 10)
{
//这里与上一节的代码略有不同
secondThread.Start();
firstThread.Start();
firstThread.Join();
secondThread.Join();
}
else
{
Console.WriteLine(Thread.CurrentThread.Name + " z = " + z);
}
}
Console.Read();
}
}
}
运行结果:
图1 图2 图3
总结:
1.上面三个图的运行结果都不一样,但有一点是相同的.主线程是最先执行的[不管新创建的线程级别如何]
2.当满足新线程启动条件后,secondThread总是先执行,是因为secondThread线程先启动了[尽管firstThread优先级高于secondThread] .
3.当secondThread运行了一小段时间后,firstThread线程接着执行.
4.当两个新创建的线程都执行完毕后,主线程继续执行.
注:
1.多线程同时工作的时候,优先级高的线程要先启动[Thread.Start()],先加入[Thread.Join()].
2.这个例子里因为启动顺序搞错了,也可以看出多线程,并不是说所有的线程同时工作,而是轮流运行的.
Thread.ThreadState 属性
这个属性代表了线程运行时状态,在不同的情况下有不同的值,我们有时候可以通过对该值的判断来设计程序流程。
ThreadState 属性的取值如下:
Aborted:线程已停止;
AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;
Background:线程在后台执行,与属性Thread.IsBackground有关;
Running:线程正在正常运行;
Stopped:线程已经被停止;
StopRequested:线程正在被要求停止;
Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);
SuspendRequested:线程正在要求被挂起,但是未来得及响应;
Unstarted:未调用Thread.Start()开始线程的运行;
WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;
上面提到了Background状态表示该线程在后台运 行,那么后台运行的线程有什么特别的地方呢?其实后台线程跟前台线程只有一个区别,那就是后台线程不妨碍程序的终止。一旦一个进程所有的前台线程都终止 后,CLR(通用语言运行环境)将通过调用任意一个存活中的后台进程的Abort()方法来彻底终止进程。
bicabo C#多线程详解(三)的更多相关文章
- Java多线程详解(三)
1)死锁 两个线程相互等待对方释放同步监视器时会出现死锁的现象,这时所有的线程都处于阻塞状态,程序无法继续向下执行. 如下就是会出现死锁的程序. 首先flag = 1,线程d1开始执行,锁住对象o1, ...
- C#多线程详解(一) Thread.Join()的详解
bicabo C#多线程详解(一) Thread.Join()的详解 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程 ...
- iOS开发——多线程OC篇&多线程详解
多线程详解 前面介绍了多线程的各种方式及其使用,这里补一点关于多线程的概念及相关技巧与使用,相信前面不懂的地方看了这里之后你就对多线程基本上没有什么问题了! 1——首先ios开发多线程中必须了解的概念 ...
- Java 多线程详解(四)------生产者和消费者
Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程: ...
- java中多线程详解-synchronized
一.介绍 当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线 ...
- python多线程详解
目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 二.线程实现 threading模块 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 互斥锁 递归锁 信号量 ...
- .NET DLL 保护措施详解(三)最终效果
针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...
- iOS开发——GCD多线程详解
GCD多线程详解 1. 什么是GCD Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,简单来说,GCD就是iOS一套解决多线程的机制,使用GCD能够最大限度简化多线程 ...
- Android 之窗口小部件详解(三) 部分转载
原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...
随机推荐
- 前端-Vue基础2
1.过滤器 前台通过后台传值,要对后台传过来的变量进行特殊处理,比如根据id转成中文等: 1.1 局部过滤器 局部过滤器只针对一个Vue实例 默认将|左侧count传递给右侧方法 {{count|fi ...
- Day5 Scanner对象学习.
Scanner对象 Java.until.Scanner 我们可以通过Scanner类来获取用户的输入. 基本语法: Scanner s = new Scanner (System . in) ; 通 ...
- linux xsel命令
xsel操作在三个寄存器上,其中一个是系统剪切板(-b).一个是默认寄存器(-p).一个是(-s)
- python -- namedtuple元组
- python -- 面向对象编程(继承、重写)
一.继承 子类可以继承父类的所有公有成员,但不能直接访问父类的私有成员,只能通过父类的公有方法间接访问私有属性或私有方法. 如: class DerviedClassName(BaseClassNam ...
- C++中dynamic_cast与static_cast浅析与实例演示
1. static_cast 1.1 static_cast语法 static_cast< new_type >(expression) 备注:new_type为目标数据类型,expres ...
- 微信小程序云开发-云存储的应用-云相册
一.准备工作 1.创建数据库表images 2.设置数据库表images的权限 二.创建图片列表页 创建图片列表页imageList,用于展示图片列表.该页面具有跳转到图片上传页面.图片列表展示.删除 ...
- PAT乙级:1094 谷歌的招聘 (20分)
PAT乙级:1094 谷歌的招聘 (20分) 题干 2004 年 7 月,谷歌在硅谷的 101 号公路边竖立了一块巨大的广告牌(如下图)用于招聘.内容超级简单,就是一个以 .com 结尾的网址,而前面 ...
- Kafka之--自动启动zookeeper & kafka 脚本
1) 首先配置SSH免密登录,在这里我用kafka(151)这台机器来作为启动脚本的存放和执行机器 [root@kafaka3 .ssh]# pwd #生成SSH KEY /root/.ssh [ro ...
- sql语句优化(持续更新)
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引.2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引 ...