1. 并发编程面临的问题
并发编程是为了让程序运行得更快,但是并不是启动更多的线程就能让程序最大限度的并发执行,通常在并发编程中会遇到下面的问题.
1.1 上下文切换
CPU通过时间片非配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务.在切换时会保存上一个任务的状态,以便这个任务再次执行时,可以在加载这个任务的状态.所以任务从保存到再加载的过程就是一次上下文切换.
1.1.1 多线程不一定比单线程快
测试多线程是否一定比单线程快 执行链接中的代码发现,当并发操作较少时,并发执行的速度比串行慢,因为并发执行时,线程有创建和上下文切换的开销.
1.1.2 如何减少上下文切换
- 无锁并发编程.多线程竞争锁时会引起上下文切换,所以多线程处理数据时可以避免使用锁(如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据).
- CAS算法.Java的Atomic包便是使用CAS算法来更新数据,而不加锁.
- 使用最少线程. 避免创建不需要的线程.
- 协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换.
1.2 死锁
造成死锁的代码 链接中的代码会造成死锁,代码中thread1和thread2互相等待对方释放锁.避免死锁的方法如下:
- 避免一个线程同时获取多个锁
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
- 尝试使用定时锁
- 对于数据库锁,加锁和解锁必须在一个连接里,否则可能解锁失败.
1.3 资源限制
程序的运行速度受限于计算机的硬件或软件资源.硬件限制有带宽的上传/下载速度,硬盘读写和CPU的处理速度;软件限制有数据库的连接数和socket的连接数等.
为了解决资源限制,硬件可以换设备,采用集群并发执行程序;
软件限制可以使用连接池将数据库和socket连接复用.