CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。
1)多线程不一定快:
多线程会存在上下文切换的开销。
2)上下文切换测量:
时长:Lmbench3
次数:vmstat
3)减少上下文方法
①无锁并发编程:Hash取模,不同线程处理不同段数据。
②CAS算法:Atomic包
③少线程
④协程:单线程多任务
4)实战:分析线程快照
①线程dump
/usr/local/java/bin/jstack 1024 > dump1024
②统计
grep java.lang.Thread.State dump1024 | awk '{print $2$3$4$5}' | sort | uniq -c
③打开dump文件
2、死锁
避免死锁方法:
①避免一个线程同时获取多个锁
②避免一个线程在锁内同时占用多个资源,尽量每个锁占用一个资源
③尝试使用定时锁lock.tryLock(timeout)
④数据库锁,加锁和解锁必须在一个连接里
3、资源限制
1)资源限制:
在并发编程,程序执行速度受限于计算机硬件资源或者软件资源。带宽上传下载速度、硬盘读写和cpu处理速度;数据库连接数和socket连接数等。
2)引发问题:
资源受限,并发执行的程序仍是串行执行,程序反而慢,增加了上下文切换和资源调度的时间。
3)解决问题:
硬件资源:考虑使用集群并行执行程序。Hadoop、自建集群。
软件资源:考虑使用资源池将资源复用。数据库、socket连接复用。
4)资源有限下进行并发编程
调整并发度。
原文》》笔记 | 面试官问我高并发的问题:并发编程的三大挑战
笔记系列↓↓↓: