一、多线程并发编程的目的是:让程序运行的更快
二、但是再多线程并发编程的时候会遇到很多年困难
1、上下文切换的问题
2、死锁的问题
3、受限于软件以及硬件的资源分配问题
三、上下文切换问题
1、前景介绍:
CPU通过个多线程分配CPU时间片的方法来实现多线程并发,CPU时间片就是CPU分配给每个线程的时间,CPU时间片非常的短暂,由于CPU不断地在多个线程之间来回切换,所以就感觉这些线程是同时进行的,也就是并发。
2、上下文切换:
CPU通过CPU世间片的分配算法来循环执行这个任务,当前任务执行一段时间后就会转到下一个任务,但是切换到下一个任务之前会保存上一个任务的状态,以便下次切换回这个任务的时候,可以接续执行。那么一个任务从被保存到再加载这一个过程就是上下文切换。
3、上下文切换给多线程并发执行带来的困难:会影响多线程执行速度
4、减少上下文切换的方法:
(1)无锁并发编程:
因为多线程可能会因为抢夺锁而引起上下文切换,可以用一些方法来避免使用锁,比如将数据的ID按照Hash算法取模分段,不同的线程处理不同的数据,这样的话就避免了不同线程要处理同一数据从而引发的抢占锁的问题,也就减少了上下文切换。
(2)CAS算法:
Java的Atomic包利用CAS算法来更新数据,从而不用加锁
(3)使用最少线程:
减少不必要的线程创建
(4)协程:
在单线程中实现多任务的调度,并在单线程中执行多个任务间的切换。
四、死锁问题
1、引起死锁的原因:
(1)线程间互相等待着对方释放锁
(2)一个线程拿到锁之后因为一些原因没有释放(死循环)
(3)一个线程拿到一个数据库锁,释放锁的时候发生了异常,没有释放掉
2、避免死锁的解决方法:
(1)避免一个线程拥有多个锁
(2)避免一个线程在锁内占有多个资源,尽量保证每个锁只占用一个资源
(3)尝试使用定时锁,使用lock。tryLock(timeout)来代替使用内部锁机制
(4)对于数据库锁,加锁解锁必须在一个数据库连接里,否则会出现解锁失败的情况
五、受限于软件以及硬件的资源分配问题
1、硬件资源限制:
(1)带宽的上传/下载速度
(2)硬盘的读写速度
(3)CPU处理速度
2、软件资源限制
(1)数据库连接数
(2)socket连接数
3、资源限制引发的问题:
本来串行的代码改成并行,但是由于资源受限,所以仍串行执行,这不仅不会加快执行,反而会变慢。
4、解决方案
针对硬件资源受限问题:
使用集群并行实行程序,就是多个机器一起运行。比如使用ODPS,Hadoop或者自己搭建的服务器群,不同的机器处理不同的数据
针对软件资源受限
使用资源池将资源复用。比如使用连接池将数据库和Socket连接复用,或者在调用对方webservice接口获取数据的时候,只建立一个连接。