• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

电商项目踩坑笔记 | 力推

技术杂谈 巷子的童年 1周前 (04-14) 26次浏览 已收录 0个评论 扫描二维码

 
# 坑1、ThreadLocal的使用
踩坑点:砍价活动中,保证砍价金额的原子性。一般使用以下这段代码来分析耗时时间,如下所示。
多线程情况下的打印结果。
线程A:赋值startTime=“2019-01-01 00:00:01”线程B:赋值startTime=“2019-01-01 00:00:02”线程A:赋值endTime=“019-01-01 00:00:05”耗时打印出:3秒
那么,问题来了,那一秒哪去了?
我们可以发现,startTime为共享变量,线程B重新赋值时会修改A已经赋予的值,所以引出了线程 ThreadLocal 变量的问题。
ThreadLocal 是每个线程中的一个集合,主要存放每个线程的局部变量,可以这样修改上面的例子。
接着,咱们来读一下ThreadLocal源码
1)获取线程本地集合
2)创建本地线程集合
3)ThreadLocal中的 get() 方法源码
小结
每个Thread维护着一个ThreadLocalMap的引用;ThreadLocalMap是ThreadLocal的内部类,用Entry来进行存储;
调用ThreadLocal的set()方法时,实际上就是往ThreadLocalMap设置值,key是ThreadLocal对象,值是传递进来的对象;
调用ThreadLocal的get()方法时,实际上就是往ThreadLocalMap获取值,key是ThreadLocal对象;
ThreadLocal本身并不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value。
正因为这个原理,所以ThreadLocal能够实现“数据隔离”,获取当前线程的局部变量值,不受其他线程影响。
疑问:ThreadLocal引发的内存泄露问题吗?
由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。
# 坑2、集合中循环删除问题
踩坑点for循环中删除参数,抛出运行时异常 java.util.ConcurrentModificationException 。
 
接着,咱们来查看List的相关源码
小结
for循环中的删除了相应的元素(标记删除),查询时过滤,导致在后面检查时发现长度不一致,以至于抛出异常。
检查
抛出
解决方案:使用迭代器处理。
编码时,解决方案:使用数据搬移,创建新的数据接收未被删除的数据,时间复杂度O(n),问题是不利于GC回收。
拓展1
需求:电商订单量以后会很大怎么分表。
方案:使用数据搬移思想,用用户唯一标识取hash,按hash值分表分的订单,存:存于相应的表中(hash值对应),查询:查询方法中增加数据搬移,从老表中分批搬移到新表中。
优点:可以横向灵活拓展订单数据,只需要指定表的个数。
拓展2
删除操作:使用标记删除,当数组没有更大的空间时在执行统一的删除操作,可类比JVM标记清楚垃圾回收算法的思想。
# 坑3、线程池的使用创建量参数问题
踩坑点延迟队列中使用线程池,如下。
publicvolatilestatic ExecutorService exec = Executors.newFixedThreadPool(9);
newFixedThreadPool:创建固定的线程数。
 
创建量和I/O和cpu核数有关
1)cpu密集型:线程数设定为cpu 核数+1
2) I/O 密集型:CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]
 

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:电商项目踩坑笔记 | 力推
喜欢 (0)
[247507792@qq.com]
分享 (0)

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00