使用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也不懂程序员,但我理解这种心情.当看到自己还算自信的专业领域中一部超越自己水平很多的作品或比自己优秀太多的人,难免会感到震惊,继而进行自我否定.就像我曾经非常喜欢写作,在杂志和校报上 ...
随机推荐
- minikube操作命令
1. 下载minikube https://storage.googleapis.com/minikube/releases/v0.16.0/minikube-linux-amd64 ch ...
- 巨蟒python全栈开发-第4天 列表&元组&range
今日内容大纲 1. 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求 列表存在索引和切片. 和字符串是一样的. 2. 相关的增删改查操 ...
- mysql_表内容_操作
1.增 语法:insert into 表 (列名,列名...) values (值,值...) # 插入单条数据 insert into 表 (列名,列名...) values (值,值...) # ...
- hdu 1257 最少拦截系统【贪心 || DP——LIS】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- mysql crete view
CREATE VIEW user_algo_view ASselect `u`.`userId` AS `UserId`,`u`.`userCode` AS `UserCode`,group_conc ...
- Mindjet MindManager 出现Runtime Error解决方案
Mindjet MindManager文件打开报错怎么解决?文件打开后提示Runtime Error!Program:C:\Program Files\MindManager 9\Mindmanage ...
- C#中的另类语法
一..net中return的另类写法: 不知道是从3.5还是从4.0开始C#语法中的return有了新的写法示例如下: public string functionDemo() { str ...
- MyBatis缓存机制-二级缓存
MyBatis二级缓存是基于namespace级别的缓存. 1.MyBatis的缓存机制整体设计以及二级缓存的工作模式 如上图所示,当开一个会话时,一个SqlSession对象会使用一个Executo ...
- HTTP协议简要介绍
1. 网络基础 TCP/IP 通常使用的网络是在TCP/IP协议簇基础上运作的. HTTP属于它内部的一个子集. TCP/IP分为4个层次, 应用层, 传输层, 网络层, 链路层. (Applicat ...
- Hbase 学习笔记5----hbase region, store, storefile和列簇的关系
The HRegionServer opens the region and creates a corresponding HRegion object. When the HRegion is o ...