一、并发编程的挑战
1 . 上下文切换
CPU 通过给每个线程分配 CPU 时间片,并且不停的切换线程执行,让我们感觉到多个线程是同时执行的,所以任务从保存到再加载的过程就是一次上下文切换
(1)减少上下文切换的方法
- 无锁并发编程 :处理多线程数据时。可以用一些方法来避免使用锁,如将数据的 ID 按照 Hash 算法取模分段,不同的线程处理不同的数据;
- CAS 算法 :Java 的 Atomic 包使用 CAS 算法来更新数据,而不需要加锁;
- 使用最小线程 :避免创建不需要的线程;
- 协程 :再单线程里实现多任务的调度,并在单线程里维持搓个任务间的切换;
2 . 死锁
锁运用的场所非常多,同时也会因为一些原因死锁,这样会造成系统功能不可用。
(1)避免死锁的方法
- 避免一个线程同时获取多个锁;
- 避免 一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源;
- 尝试使用定时锁,使用 lock.tryLock ( timeout ) 来代替使用内部锁机制;
- 对于数据库锁,加锁和解锁必须在同一个数据库链接里,否则会出现锁失败的情况;
3 . 资源限制的挑战
资源限制 是指在进行并发编程时,程序的执行速度受限于计算机硬件资源或者软件资源。
硬件资源限制 :带宽的上传/下载速度、硬盘读写速度、 CPU 的处理速度;
软件资源限制 :数据库的连接数、socket 连接数;
(1)如何解决资源限制问题
硬件资源限制 :可以考虑使用集群并行执行程序,例如 ODPS 、Hadoop 或者自己搭建的集群,不同的机器处理不同的数据;
软件资源限制 :可以考虑使用资源池将资源复用,例如使用连接池将数据库和 socket 连接复用,或者在调用对方 webservice 接口获取数据时,之建立一个连接