第一章 : 并发编程的挑战

1 : 上下文切换
  • CPU通过时间片分配算法来循坏执行任务,当前任务执行一个时间片后会切换到下一个任务,但是在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以加载这个任务状态
  • 任务从保存到再加载的过程就是一次上下文切换
1.1 : 多线程一定快么
  • 答案是不一定,线程有创建和上下文切换的开销,当并发操作不超过百万次的时候,并发执行耗时 > 串行执行耗时
1.2 : 测试上下文切换次数和时长
  • 使用Lmbench3可以测量上下文切换的时长(Lmbench3是一个性能分析工具)
  • 使用Vmstat可以测量上下文切换的次数,vmstat中的cs列表示上下文切换的次数
1.3 : 如何减少上下文切换
  1. 无锁并发编程 : 多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照hash算法取模分段,不同线程处理不同段的数据
  2. CAS算法 : Java的Atomic包使用CAS算法来更新数据,而不需要加锁
  3. 使用最少线程 : 避免创建不需要的线程,比如任务少,创建较多线程来处理,会造成大量线程都处于等待状态
  4. 协程 : 在单线程里实现多任务调度,并在单线程里维持多个任务间的切换
1.4 : 减少上下文切换实战
  1. 使用jstack命令dump线程信息
  2. 统计所有线程分别处于什么状态
  3. 打开dump文件查看处于WAITING(onobjectmonitor)在做什么
  4. 减少JBOSS的工作线程数,找到JBOSS线程池配置信息,将maxThreads降低
  5. 重启JBOSS,再dump线程信息
2 : 死锁
  • 原因 : 线程T1在获得锁L1的时候,在没有释放锁L1的情况下,又去申请获得锁L2,线程T2已经获得了锁L2,在释放锁L2之前又得去访问锁L1
  • 处理
  • 避免在一个同步方法内调用其他对象的延时方法和同步方法
  • 避免一个线程同时获取多个所
  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
  • 尝试使用定时锁,使用lock.tryLock(timeout)来代替使用内部锁机制
  • 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
3 : 资源限制的挑战
  1. 资源限制 : 是指在进行并发编程时,程序的执行速度受限于计算机硬件资源或软件资源,硬件资源限制有带宽的上传/下载速度,硬盘读写速度,CPU的处理速度.软件资源限制有数据库连接等和Socket连接数等
  2. 资源限制问题 : 将代码速度加快的原则是将代码的串行执行部分换成并发执行,但是如果这段串行的代码并发执行,因为受限于资源,仍然在串行执行,这时候程序不仅不会加快执行,反而会更慢,因为增加了上下文切换和资源调度的时间
  3. 解决资源限制问题 : 对于硬件资源控制,可以考虑使用集群并发执行程序,对于软件资源限制,可以考虑使用资源池将资源服用,比如使用连接池将数据库和Socket连接复用,或者在调用对方webservice接口获取数据时,只建立一个连接
  4. 资源限制情况下并发编程 : 更具不用资源调整程序的并打度.
4 : 本章小结

并发下如果出现问题,应该使用JDK并发包提供的并发容器和工具类来解决并发问题,因为这些类都已经通过充分的测试和优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值