书行天下
(1)上下文切换
上下文切换:cpu通过时间片来执行任务,时间片结束后,需要切换线程。任务从保存到再加载的过程就是上下文切换。
上下文切换存在的问题:上下文切换存在时间的开销,因此线程个数对系统存在影响。
如何减少上下文切换:无锁并发编程、CAS算法、使用最少线程、协程。
- 无锁并发编程 :多线程竞争锁存在线程切换,例如多线程处理数据时,将数据id经过hash算法取模分段到不同线程计算,避免使用锁。
- CAS算法:比较、交换、自旋
- 适当数量的线程
- 协程:在单线程中实现多任务调度,并在单个线程中维持多个任务之间的切换。
jstack命令dump线程信息命令:
jstack 21121 > /home/user/dump12. #dump出文件
grep java.lang.Thread.State dump12 | awk '{print $2$3$4$5}' | sort | uniq -c. #统计线程状态
#打开dump文件,查看不同状态线程都在做什么
(2)死锁
锁的使用可能会带来死锁,两个线程同时在等待对方释放锁就会引起死锁。
例如t1线程拿到锁后抛出异常没有释放锁导致其他线程无法获取锁。
如何避免死锁:
- 避免同一个线程同时获取多个锁
- 避免一个线程在锁内同时占用多个资源
- 使用定时锁代替
- 对于数据库锁,加/解锁必须在一个数据库连接里,否则会出现解锁失败。
(3)资源限制
如何在资源限制情况下并发编程:需要根据资源情况调整程序的并发度。
结论:使用java并发编程时,尽量使用java并发容器和工具类解决并发问题。