12:Java并发编程实战
1:生产者和消费者模式下的并发案例
生产者和消费者之间通过阻塞队列来进行通信,阻塞队列相当于一个缓存区,平衡了生产者和消费者之间的处理能力。
(1)多生产者、多消费者场景
(2)线程池与生产消费者模式
A: java中线程池其实也是一种生产者和消费者模式的实现方式。那它为啥比使用一个阻塞队列来实现实现生产者和消费者模式高明呢?
B: 如何使用线程池来实现多生产者和消费者模式呢?(可以考虑一个线程池1主要处理Io密集型任务,线程池2主要处理Cpu密集型任务。)
2:如何在生产线上,快速定位问题?
通常做法:看日志、系统状态、dump线程
细化通常的做法:
(1)在Linux命令下使用top命令查看每个进程的情况。
(2)再使用top的交互命令数字1查看每个cpu的性能数据。
CPU参数含义:
(3)使用top的交互命令H查看每个线程的性能信息。可能会出现下面几种情况:
第一种情况:某个线程CPU利用率一直是100%,则说明是这个线程有可能有死循环,那么请记住这个PID。
第二种情况:某个线程一直在TOP10的位置,这说明这个线程可能有性能问题。
第三种情况:CPU利用率高的几个线程在不停变化,说明并不是由某一个线程导致CPU偏高。
3:如何开发一个性能测试工具呢?
原理:用户写一个java程序向服务器端发起请求,这个工具会启动一个线程池来调度这些任务,可以配置同时启动多少个线程、发起请求次数和任务间隔时长。将这个程序部署在多台机器上执行,统计出QPS和响应时长。
4:性能测试中使用的命令?
查看网络流量:cat /proc/net/dev
查看系统平均负载:cat /proc/loadavg
查看系统内存情况:cat /proc/meminfo
查看CPU的利用率:cat /proc/stat
使用netstat命令查询有多少台机器连接到压测程序上:netstat -nat | grep 12200 -c 注意:12200是压测程序的端口
使用netstat命令查看已经使用了多少个数据库连接:netstat -nat | grep 3306 -c
使用ps命令查看下线程数是否增加了:ps -eLf | grep java -c
5:java中异步任务池的使用?
简单说一下背景:线程池只能处理本机的任务,在集群环境下不能有效地调度所有机器的任务。比如:一个任务刚扔进线程池,运营线程池的程序重启啦,那么线程池里的任务就会丢失。
任务池的任务隔离:异步任务种类比较多,如:抓取网页任务、同步数据任务。不同类型的任务优先级不一样。如果任务类型比较少,建议用任务类型来隔离;如果任务类型比较多,比如几十个,建议采用优先级的方式来隔离。
任务池的重试策略:根据不同的任务类型设置不同的重试策略。重试间隔随着次数的增加,时间不断增长,比如间隔几秒、几分钟到几小时。
使用任务池的注意事项:任务必须无状态。任务不能在执行任务的机器中保存数据。比如:某任务时处理上传文件,任务属性里有文件上传路径,如果文件上传到机器1,机器2获取到了任务则会处理失败。因为机器1和机器2是隔离的。
异步任务的属性:包括任务名称、下次执行时间、已执行次数、任务类型、任务优先级和执行时的报错信息(用于快速定位问题)
并发编程IBM博文:
https://www.ibm.com/developerworks/cn/java/j-concurrent/?ca=j-r#JAVAZ%E7%BA%BF16