使用ConcurrentLinkedQueue惨痛的教训
服务端原本有个定时任务对一个集合ArrayList 中的消息做处理。 因为考虑到处理消息是先进先出原则,所以优化的时候考虑改用ConcurrentLinkedQueue 当时没仔细深入研究过这个集合就匆匆上线了。结果刚上线第二天就出问题了。服务端一次优化演变成了一个缺陷,还好及时回退了版本,后果才不是很严重。
回退后对ConcurrentLinkedQueue 做了一个简单的测试代码如下:
- import java.util.concurrent.ConcurrentLinkedQueue;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class ConcurrentLinkedQueueTest {
- private static ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
- private static int count = 100000;
- private static int count2 = 2; // 线程个数
- private static CountDownLatch cd = new CountDownLatch(count2);
- public static void dothis() {
- for (int i = 0; i < count; i++) {
- queue.offer(i);
- }
- }
- public static void main(String[] args) throws InterruptedException {
- long timeStart = System.currentTimeMillis();
- ExecutorService es = Executors.newFixedThreadPool(4);
- ConcurrentLinkedQueueTest.dothis();
- for (int i = 0; i < count2; i++) {
- es.submit(new Poll());
- }
- cd.await();
- System.out.println("cost time "
- + (System.currentTimeMillis() - timeStart) + "ms");
- es.shutdown();
- }
- static class Poll implements Runnable {
- @Override
- public void run() {
- // while (queue.size()>0) {
- while (!queue.isEmpty()) {
- System.out.println(queue.poll());
- }
- cd.countDown();
- }
- }
- }
运行结果:
costtime 2360ms
改用while (queue.size()>0)后
运行结果:
cost time 46422ms
结果居然相差那么大,看了下ConcurrentLinkedQueue的API 原来.size() 是要遍历一遍集合的,难怪那么慢,所以尽量要避免用size而改用isEmpty().
总结了下, 在单位缺乏性能测试下,对自己的编程要求更加要严格,特别是在生产环境下更是要小心谨慎。
使用ConcurrentLinkedQueue惨痛的教训的更多相关文章
- 使用ConcurrentLinkedQueue惨痛的教训【转】
转自:http://blog.csdn.net/jackpk/article/details/49634577 服务端原本有个定时任务对一个集合ArrayList 中的消息做处理. 因为考虑到处理消息 ...
- ScrollView 尽量避免嵌套RelativeLayout,非常惨痛的教训
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&q ...
- 记录一个bootstrap惨痛的错误
记录一个bootstrap的错误,这个错误因为我删除了一个class就导致了页面上显示的错误,这是一个惨痛的教训,特此记录,提醒自己在做前端的修改时,一定要慎之又慎.如果真的要做改动,改完之后也要测一 ...
- Gulp 常用插件
插件使用注意事项: 插件需要先 npm/cnpm install xx --save-dev gulp taskname,如果 task 已经设置成 default 的依赖,直接 gulp 即可 ta ...
- iOS---FMDB数据升级
本人在这里重要强调一下!!! 看这里,看这里,看这里,重要的事说三遍. 本人在项目开发中,由于需求问题,不得不对已经建立好的数据库进行修改(添加字段),我就很随意的直接添加了对一个的字段,运行一下,数 ...
- 【BZOJ1497】[NOI2006]最大获利 最小割
裸的最小割,很经典的模型. 建图:要求总收益-总成本最大,那么将每条弧与源点相连,流量为成本,每个收益与汇点相连,流量为收益,然后每条弧与它所能到达的收益相连,流量为inf. 与源点相连的是未被选中的 ...
- [转]浅谈CSRF攻击方式
在CSDN中看到对CSRF攻击的原理及防护文章,讲解浅显易懂,特转之: 来源:http://blog.csdn.net/fationyyk/article/details/50833620 一.CSR ...
- 浅谈CSRF攻击方式
一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...
- 看完《Thinking in Java》后,我觉得自己就是一个不懂编程的小孩子,如何快速摆脱这种自卑感
我虽然不懂java也不懂程序员,但我理解这种心情.当看到自己还算自信的专业领域中一部超越自己水平很多的作品或比自己优秀太多的人,难免会感到震惊,继而进行自我否定.就像我曾经非常喜欢写作,在杂志和校报上 ...
随机推荐
- mysql中修改字段的类型
修改表字段的类型: ALTER TABLE 表名 MODIFY COLUMN 字段名 字段类型定义 如:将movie_mark修改为浮点型 alter table new_playing_video ...
- Spoken English Practice(You know we can't afford that. How do other people do it? Other people make more twenty-four thousand a year. )
绿色:连读: 红色:略读: 蓝色:浊化: 橙色:弱读 下划线_为浊化 口语蜕变(2017/7/9) 英 ...
- module使用
官方文档:http://modules.sourceforge.net/ 加载 module load 卸载 module unload 查看已加载 module list 查看可用 module a ...
- spring 实现定时任务
spring实现定时任务超级简单.比使用quartz简单,比使用timer强大.如下是一个简单的springboot任务,启用了定时任务 @SpringBootApplication@Componen ...
- action接收请求参数
一.采用基本类型接收请求参数(get/post)在Action类中定义与请求参数同名的属性,struts2便能接收自动接收请求参数并赋给同名属性. action的代码: public class Pa ...
- Hadoop的eclipse1.1.2插件的安装和配置
我的集群使用的hadoop版本是hadoop-1.1.2.对应的eclipse版本也是:hadoop-eclipse-plugin-1.1.2_20131021200005 (1)在eclipse的d ...
- BCH码
http://baike.baidu.com/link?url=CfLtm9DigwWdup-9VJP99RG65NgaVOXfrnjT61ogP7au0QOrlypq72k67B0s1Ey-Q1yD ...
- Java集合(9):ConcurrentHashMap
一.ConcurrentHashMap介绍 我们可以在单线程时使用HashMap提高效率,而多线程时用Hashtable来保证安全.但是,HashMap中未进行同步考虑,而Hashtable则使用了s ...
- Python 字符串连接问题归结
一.概述 Python 字符串连接场景较为普遍.由于编者对 Java 等语言较为熟悉,常常将两者语法混淆. 加之,Python 语法较为灵活.例如,单单实现字符串连接,就有数种方法.在此,一并归结! ...
- JS 原生JS 判断滚动条滑动到底部
window.addEventListener("scroll", function(event) { var scrollTop = document.documentEleme ...