一:并发编程面临的挑战
(1)上下文切换问题
(2)死锁问题
(3)受限于硬件和软件资源的问题
&&注意点:并发编程的累加操作不超过百万次,多线程的执行速度要比单线程慢。因为线程有创建和上下文切换的开销。
二:如何减少上下文切换?
(1)无锁并发编程。
--->多线程竞争锁时,会引起上下文切换,所以多线程处理数据时候,可以用一些办法避免使用锁。
--->如将数据id按照hash算法取摸分段,不同线程处理不同段的数据。
(2)CAS算法
--->java的Atomic包使用了CAS算法更新数据,而不需要加锁。
(3)使用最少线程
--->避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态
(4)协程
--->在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。
三:如何避免多线程死锁?
(1)避免一个线程同时获取多个锁
(2)避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
(3)尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
(4)对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。
四:如何解决资源限制?
(1)什么是资源限制
--->硬件资源限制有带宽的上传/下载速度。
--->硬盘的读写速度和cpu处理速度。
--->数据库的连接数和socket连接数
(2)资源限制引发的问题
--->并发编程中,将代码执行速度加快的原则是将代码中串行的部分变成并发执行。
--->由于受限于资源,所设计的并发其实仍然在串行执行,这时候程序不仅不会加快执行,反而会更慢,因为增加了上下文切换和资源调度的时间。
(3)如何解决资源限制的问题。
--->对于硬件资源限制,可以考虑使用集群并行执行程序。单机有限,多机运行。比如:集群。
--->对于软件资源的限制,可以考虑使用资源池将资源复用。比如使用连接池将数据库和socket连接复用。
--->根据不同的资源限制调整程序的并发度,比如下载文件程序依赖两个资源--带宽和硬盘的读写速度。有数据库操作时,设计数据库连接数,如果sql语句执行非常快,而线程的数量比数据库的连接数大很多,某些线程会被阻塞,等待数据库连接。