1.1上下文切换
多线程不一定就比单线程快,因为多线程存在上下文切换的问题、死锁的问题等问题,
测试循环累加和累减
image.png
当执行次数不超过一定次数的时候,并发执行速度会比串行执行慢,因为有上下文切换的开销等问题。
减少上下文切换
方法有无锁并发编程、CAS算法、使用最小线程和使用协成。
无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以使用一些办法避免使用锁,例如将数据的ID按照hash算法取模分段,不同的线程处理不同段的数据。
CAS算法:java的Acomic包使用CAS 算法来更新数据,而不需要加锁。
使用最小线程:避免创建不需要的线程,比如任务很少,但是创建了很多的线程来处理,这样会造成大量线程都处于等待状态。
协程:在单个任务里面维持多个任务的调度和切换。
jstack 命令可以查看线程信息,
1.2死锁
一旦出现死锁,业务一般是可感知的,因为不能继续提供服务了,只能通过dump线程来看。
避免死锁:
- 避免一个线程同时获得多个锁
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
- 尝试使用定时锁,使用lock.tryLock(timeout)来代替内部锁的机制。
- 对于数据库锁、加锁和解锁在一个数据库连接,否则会出现解锁失败的情况。
1.3 资源限制的挑战
资源限制:
- 硬件限制:带宽,硬盘读写 CPU处理速度。(部署集群,等)
- 软件限制:数据库的连接数和socket连接数。(使用连接池、Socket等等等)
网友评论