异步和多线程的区别和专注,要哪个

ASP.Net+Android+IO开发S、.Net培训、期待与您交流!
& 看了黑马的教学视频,才真正了解了多线程的实现过程。
& 谈到多线程,我们常与之对应的就是单线程。要实现多线程,首先就要给多线程写一个任务(就是一个方法),当我们启动多线程时,就会调用传递过来的委托,委托就会执行相应的方法。
& 一般情况下,我们实现多线程的步骤如下:
1.编写多线程要执行的方法;
2.引用命名空间System.T
3.实例化一个多线程,并传入所要执行的方法;
4.调用线程里的start方法启动线程。
其实创建线程,用start启动后,就是标记该线程可以被CPU执行。常常看见在窗体中运行一个很长的循环,窗体就不能移动,这是因为单线程时,窗体的自己的线程执行任务去了,当你想拖动窗体时,就没人来执行你这个窗体的任务了。使用多线程后,就是直接标记可被CPU执行,就相当于我从外面找人来完成这个循环的任务。
下面举一个例子:
&private void button1_Click(object sender, EventArgs e) &&&&&&&
{ &&&&&&&&&&&
Thread td1 = new Thread(Count); &&&&&&&&&&&
td1.Name = "线程一"; &&&&&&&&&&&
td1.IsBackground = &&&&&&&&&&&
td1.Start();
&&&&&&&&&&&
Thread td2 = new Thread(Count); &&&&&&&&&&&
td2.Name = "线程二"; &&&&&&&&&&&
td2.IsBackground = &&&&&&&&&&&
td2.Start(); &&&&&&& } &&&&&&&
protected void Count() &&&&&&&
{ &&&&&&&&&&& int a = 0; &&&&&&&&&&&
&& &for (int i = 0; i & 2000; i++) &&&&&&&&&&&
{ &&&&&&&&&&&&&&&
&&&&& &a = Convert.ToInt32(label1.Text); &&&&&&&&&&&&&&&
&&&&&& a++; &&&&&&&&&&&&&&
&&&&& label1.Text = a.ToString(); &&&&&&&&&&&&&&
&&&&& Console.WriteLine("a={0} {1}",a.ToString(),Thread.CurrentThread.Name); &&&&&&&&&
&&&&&&& & } &
&&&&&&& private void Form1_Load(object sender, EventArgs e) &&&&&
&& { &&&&&&&&&&&
&&&&&&&&&&&&& label1.Text ="0"; &&&&&&
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! 详细请查看:http://edu.csdn.net
阅读(...) 评论()299被浏览5,908分享邀请回答958 条评论分享收藏感谢收起233 条评论分享收藏感谢收起写回答4,447被浏览212,771分享邀请回答95825 条评论分享收藏感谢收起5添加评论分享收藏感谢收起多线程编程一些注意点 - 简书
多线程编程一些注意点
由于多线程编程的坑非常多,一不小心就会掉进去,然后调试好久好久。自己在使用多线程编程的场合只有几次,用java中的多线程读写redis和HBase数据,对java不是特别了解,遇到不会的去查资料;还有一次是大学时自己写的在当时看来是个大程序,因为集成了好多”高深“的东西,现在想想还是年幼无知啊,探索心较重。当时写的多线程并没有遇到什么大问题,中规中矩的。目前工作中用到的是单进程单线程模型。还是多踩点坑,多遇到困难,多去查资料才好~下面会列出自己平时看得文章和书籍中讲解多线程编程中需要注意的一些点,主要包括死锁和调试,非法内存访问和怎么定位;伪共享和volatile,共享对象的存活,还有其他,更详细的可以Google之。〇:线程安全的定义[Linux多线程编程]多个线程访问数据时,能表现出正确的行为;无论操作系统如何调度线程,无论这些线程的执行顺序如何交织;调用端代码无须额外的同步;一:死锁与定位死锁的定义和防止死锁可以参考操作系统教材。由于在多线程中需要对共享资源的访问[这里假设共享资源的生命周期随进程],可能造成A线程读的时候被B线程写了,为了防止数据的一致性和完整性,需要加锁去保证。锁有好几种,但较简单的是在栈上构造对象时构造函数lock,处理完后栈反解自动调用析构函数unlock,这样也不会忘记unlock了。需要注意的是:加锁的顺序;锁的粒度大小;或者使用线程本地存储;当发生死锁时,如何定位呢?这里使用GDB打出当前线程的调用栈,并打印锁的值,然后分析周边代码逻辑,也可以使用pstack;http://www.ibm.com/developerworks/cn/linux/l-cn-deadlock/二:内存非法访问及定位这类问题比较头疼,正常的情况下立即core给你机会去调试和分析,否则运行了好久core在了离异常代码很远处了,或者上线了才出现问题,而且多线程充满了不确定性。主要还是写代码时认真点。这个问题不像对空指针解引用好对付,需要结合汇编分析。非法内存访问可能造成函数的返回地址被改写,修改了其他数据,引用到了一个不存在的地址或受操作系统保护的区域。以前的文章中也记录了相关分析思路,如dmesg和addr2line定位到哪个地址,然后对应到该汇编代码。工具的话如valgrind,mprotect等,GDB要是能定位出真的是太幸运了。http://blog.csdn.net/killmice/article/details/三:伪共享和volatile作用volatile的出现也与多线程有一定的关系,从字面意思上理解是“易变性”的意思,告诉编译器每次读该变量得重新从内存中加载,而不是使用寄存器的内容。volatile的其他特性如“不可优化性”:不要对变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行;至于“顺序性”:能够保证Volatile变量间的顺序性,编译器不会进行乱序优化。volatile变量与非volatile变量的顺序,编译器不保证顺序,可能会进行乱序优化,如:global int iErrorCode = 0volatile bool bFlag = falseThreadOne(){iErrorCode = 1; bFalse = true}ThreadTwo(){ if (bFalse == true) {//use iErrorCode}}这段代码看似没有问题,但是因为非volatile的iErrorCode和volatile的bFlag可能被编译器进行乱序优化,导致ThreadOne中bFalse = true先执行,然后切换至线程ThreadTwo,if判断成立,就使用了本应该iErrorCode = 1而现在却为0了。解决办法就是happens-before,大致意思是保证在执行ThreadTwo的第一行代码前得执行完ThreadOne的代码,比如加锁。这篇博客有详细介绍:http://hedengcheng.com/?p=725简单介绍下false sharing,即伪共享,由于CPU多核架构,每个core有自己的缓存,举个栗子,定义int32_t iData[2],线程A读写iData[0],线程B读写iData[1],那么当加载cache line值ThreadA时,由于cache一致性的原因,写了iData[0]导致ThreadB的cache line失效,得重新加载,重复相同的动作,严重影响性能。可参考网上资料。解决办法:填充,使得两个线程加载不同的cache line。http://blog.csdn.net/wdzxl198/article/details/四:多线程中的单例模式单例模式是比较常用的一种设计模式,如果某个系统只能有一种资源存在,那么十有八九是它了。但对于不同的场景写好单例模式也不容易。我工作中因架构特殊,具体业务模块启动前这些单一资源已初始化完备,具体模块直接获取。写的单例也很简单,比如这样:class CSingleton{public:
static CSingleton * GetInstance()
static CSingleton m_O
return &m_O
//more};然后其他唯一的资源类继承它,这样当第一次被调用时分配资源。这种对于单进程单线程是没有问题的,单对于多线程来说就有问题了。于是就有了好些典型的解决方案[伪代码]:方案一[double check]:CSingletonResource * Getinstance()1
if pObj is null then2
pObj is null then4
pObj = new CSingletonResource()5
unlock()看似没有问题,假设如下A,B两个线程,A先执行则成功lock,A执行4,4语句会:1)先分配一块内存,2)再在该内存上调用构造函数进行初始化,3)赋值给pObj,顺序可能会被cpu指令重排,有可能导致2)和3)的顺序可以交换,故如果先赋值再构造,此时B线程获得CPU,B判断pObj不为空,则使用它,然而B没有办法确定这块内存到底有没有初始化,或者只初始化了一半,所以就有问题了[在4处加个临时变量就没问题了,pTemp = new CSingletonResource(),pObj = pTemp];这里要是分配内存异常了,就会发生无法释放锁,可以使用RAII。方法二:这种方法不易想到,就是定义static pthread_once_t m_Once的变量,然后被赋值为:PTHREAD_ONCE_INIT,如:static CObj * GetInstance(){
pthread_once(&m_Once, &CObj::InitData());
return m_pO}不过有个坏处就是每次GetInstance调用pthread_once函数,不过底层实现还是使用互斥锁和条件变量来保证由pthread_once()指定的函数执行一次,pthread_once()函数的实现原理可以参考pthread_once相关的资料。还有其他一些实现可能从效率方面差强人意...五:对象生死与多线程这部分想单独开一篇介绍...下面摘自TeamTalk的多线程框架:未完待续....
从事Linux C/C++服务器后台开发;专注于C/C++,对底层,算法与数据结构,网络编程,代码优化和重构,高性能高并发和架构感兴趣;热爱开源,技术分享;
联系方式[QQ]:
转自:Youtherhttps://www.cnblogs.com/youtherhome/archive//2964195.html 1. 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solar...
引用自多线程编程指南应用程序里面多个线程的存在引发了多个执行线程安全访问资源的潜在问题。两个线程同时修改同一资源有可能以意想不到的方式互相干扰。比如,一个线程可能覆盖其他线程改动的地方,或让应用程序进入一个未知的潜在无效状态。如果你幸运的话,受损的资源可能会导致明显的性能问...
Java8张图 11、字符串不变性
12、equals()方法、hashCode()方法的区别
13、Java异常类的层次结构
14、集合类的层次结构
25、Java同步
37、堆和栈
38、Java虚拟机运行时数据区域
Java 基础思维导图,让 Java 不再难懂 - 工具资源 - 掘金思维导图的好处 最近看了一些文章的思维导图,发现思维导图真是个强大的工具。了解了思维导图的作用之后,觉得把它运用到java上应该是个不错的想法,这样回顾知识点的时候一目了然,快速知道自己的短板。 思维导图...
Java8张图 1 1、字符串不变性
1 2、equals()方法、hashCode()方法的区别
1 3、Java异常类的层次结构 1 4、集合类的层次结构 2 5、Java同步
3 7、堆和栈
3 8、Java虚拟机运行时数据区域
3 一、Ja...
早晨五点20出门,天才蒙蒙亮。路遇打车的、坐地铁的全是跑马人或陪跑马人。在离奥体东还有三四站路的地铁上已相当拥挤。眼望乌央央的人出地铁,不由感叹是什么样的盛会,吸引了这么多人早起赶奔。后来听说今天有21000人参赛,再加上志愿者,安全保卫人员,服务人员。真是诺大的体育场抬个...
今天老何与大家分享Java中的基本运算,从购物车说起吧!现在我们已经习惯了网上购物,每次购物首先会把心仪的物品放进购物车,然后在购物车中进行选择操作或修改数量,最后由系统计算出相关金额,提交生成订单。
这是我们看到的页面操作,那么在后台系统(计算机)中是如何进行计算的呢...
你是非常喜欢挑战困难。 因此,意向工作的地方是一个每天都可以接受有趣,有挑战性问题的岗位。 经历渐长,我慢慢懂得,凡是有答案的都是小事,大事则只有取舍,而取舍人各不同。小事都能取巧,大事则只能拼实力:努力,耐力,爆发力。我在持续用力。希望你也一样。记住,你的价值观决定了选择...
这个问题也是在项目开发中遇到的,在游戏中要显示用户的头像,但用户头像是来自微信的网址,而cocos creator必须发布成nitave才会支持跨域。研究了好久也查了很多资料。下面代码亲测可有效跨域。以ajax异步将微信的图片地址发送到PHP的服务端转成base64码。然后...
【前世今生】 从歙县县城西北的许村出发,到黄山市黄山区(原太平县)谭家桥镇,有一条全长约30里的古道,这就是千年古官道——箬岭古道,也称徽青古道,是目前黄山市道路最长的一条古道。这条古道始建于隋朝,是连接古徽州府和安庆府的重要官道。箬岭古道位于黄山区、歙县以及宣城市的绩溪县...他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 为什么要用多线程 的文章

 

随机推荐