1.开篇
2017-04-19 本文已影响0人
炫迈哥
多线程的优势
- 当拥有多核处理器时,每条线程只能占用一个cpu,多线程可以充分发挥多cpu的威力;
- 即便是在单核处理器上,多线程处理io频繁的工作时(io进行中处理器会处于空闲状态),多条线程同时执行可以充分利用这个空闲时间片,提高系统吞吐率,像nodejs这样单线程基于事件队列异步处理的方式就是这个道理。
- 不是很重要的:使更加简单,把不同的任务划分在不同的线程中执行(以人类思考问题的方式),把任务自身的执行,任务什么时候需要同步,什么节点需要汇总等分离开形成单独的问题。
- 。。。。
带来的风险
竞态条件:当多个线程竞争访问同一个资源时,如果对访问顺序敏感,就称存在竞态条件。
最常见的静态条件:
- 先检查后执行,如延迟初始化(如:单例)
jvm虚拟机栈,每一个线程运行时都有一个线程栈,
线程先从主存拷贝数据到本地内存,读写都在本地内存中进行,在某个时刻(线程退出或者什么)将变化的值写回主存。
- 安全性问题(永远不发生糟糕的事情):由于竞态条件导致对共享数据的操作完全无法预期
- 活跃性问题(某件正确的事情最终会发生):当某个操作无法继续进行下去永久停留在那里了,就产生了活跃性问题。单线程中的死循环就是一种情况,多线程中有以下常见的几种情况:
1.死锁。多条线程相互等待对方释放锁,形成死锁。产生的四个必要条件:1)互斥,锁只能由一条线程持有,2)不可抢占,一条线程持有时,另外的线程不能强制剥夺 3)请求另外的锁时依然保持已经持有的锁(哲学家就餐问题,拿不到其他的锁,就一起释放现有的所有锁,就是避免产生这个条件的) 4)循环等待,形成环状等待锁的链路。(详细内容后续会有)
2.活锁,任务没有被阻塞,由于不满足某个条件一直重试,失败,重试,失败。(有可能自行解开的)
3.饥饿,由于线程优先级关系或者一些其他不公平的竞争条件,导致一些低优先级的线程永远也无法被执行。
- 性能问题:
- 上下文切换代价大,cpu消耗在线程调度上(”保存线程A的执行现场“然后”载入线程B的执行现场”)
- 锁粒度太大导致并发性能降低无限接近于单线程。
- 会抑制一些编一起的优化操作,如指令重排序等,同步共享主存,所有读写都会作用在主存上,增加了共享内存主线上的流量。