瀑布流的网站,网站建设工程师的职位要求,学做衣服网站有哪些,显示网站翻页代码一、ThreadLocal在多线程环境中没有清理
由于ThreadLocal是和线程绑定的#xff0c;如果线程被复用了#xff0c;也即使用了线程池#xff0c;那么ThreadLocal中的值是可能被复用的#xff0c;这个特性如果是开发者没有预料到的#xff0c;那么会产生很大的问题。例如如果线程被复用了也即使用了线程池那么ThreadLocal中的值是可能被复用的这个特性如果是开发者没有预料到的那么会产生很大的问题。例如在JAVA web应用中我们通常会使用很多ThreadLocal来保存一次请求的不同上下文信息其中就包含登录用户如果一次请求完成后没有清理掉当前登录用户信息那么当另外一个用户的请求进来就会使用上一个用户如果是涉及到数据写入将直接导致数据错乱造成严重生产问题。
二、ConcurrentHashMap使用的问题
ConcurrentHashMap提供的能力是保证单个操作在多线程环境下是安全的。如果有一段逻辑是先读取size大小在决定是否往map里put()那么这段逻辑必然产生并发问题。因为错误理解的ConcurrentHashMap的能力。解决办法是用加锁的方式控制并发。
三、CopyOnWriteArrayList使用的问题
CopyOnWrite 是一个常用的技术Linux、Redis中都用到了。在 Java 中CopyOnWriteArrayList 虽然是一个线程安全的 ArrayList但因为其实现方式是每次修改数据时都会复制一份数据出来所以有明显的适用场景即读多写少或者说希望无锁读的场景。
//测试并发写的性能
GetMapping(write)
public Map testWrite() {
ListInteger copyOnWriteArrayList new CopyOnWriteArrayList();
ListInteger synchronizedList Collections.synchronizedList(new ArrayList());
StopWatch stopWatch new StopWatch();
int loopCount 100000;
stopWatch.start(Write:copyOnWriteArrayList);
//循环100000次并发往CopyOnWriteArrayList写入随机元素
IntStream.rangeClosed(1, loopCount).parallel().forEach(__ - copyOnWriteArrayList.add(ThreadLocalRandom.current().nextInt(loopCount)));
stopWatch.stop();
stopWatch.start(Write:synchronizedList);
//循环100000次并发往加锁的ArrayList写入随机元素
IntStream.rangeClosed(1, loopCount).parallel().forEach(__ - synchronizedList.add(ThreadLocalRandom.current().nextInt(loopCount)));
stopWatch.stop();
log.info(stopWatch.prettyPrint());
Map result new HashMap();
result.put(copyOnWriteArrayList, copyOnWriteArrayList.size());
result.put(synchronizedList, synchronizedList.size());
return result;
}//帮助方法用来填充List
private void addAll(ListInteger list) {
list.addAll(IntStream.rangeClosed(1, 1000000).boxed().collect(Collectors.toList()));
}//测试并发读的性能
GetMapping(read)
public Map testRead() {
//创建两个测试对象
ListInteger copyOnWriteArrayList new CopyOnWriteArrayList();
ListInteger synchronizedList Collections.synchronizedList(new ArrayList());
//填充数据
addAll(copyOnWriteArrayList);
addAll(synchronizedList);
StopWatch stopWatch new StopWatch();
int loopCount 1000000;
int count copyOnWriteArrayList.size();
stopWatch.start(Read:copyOnWriteArrayList);
//循环1000000次并发从CopyOnWriteArrayList随机查询元素
IntStream.rangeClosed(1, loopCount).parallel().forEach(__ - copyOnWriteArrayList.get(ThreadLocalRandom.current().nextInt(count)));
stopWatch.stop();
stopWatch.start(Read:synchronizedList);
//循环1000000次并发从加锁的ArrayList随机查询元素
IntStream.range(0, loopCount).parallel().forEach(__ - synchronizedList.get(ThreadLocalRandom.current().nextInt(count)));
stopWatch.stop();
log.info(stopWatch.prettyPrint());
Map result new HashMap();
result.put(copyOnWriteArrayList, copyOnWriteArrayList.size());
result.put(synchronizedList, synchronizedList.size());
return result;
}