日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
不要在線上濫用CopyOnWriteArrayList,姿勢(shì)不對(duì)性能真的很糟糕

從JDK1.5版本,JAVA提供了線程安全的List增強(qiáng)版CopyOnWriteArrayList,其保持線程安全的方式是:每次修改數(shù)據(jù)時(shí),不會(huì)直接修改數(shù)據(jù),而是把數(shù)據(jù)復(fù)制出來(lái)一份,對(duì)復(fù)制出來(lái)的數(shù)組進(jìn)行操作。

通過(guò)這樣的機(jī)制,可以極大程度的提升讀的并發(fā)性能,所以對(duì)于CopyOnWriteArrayList來(lái)說(shuō),非常適合讀多寫(xiě)少或者無(wú)鎖的場(chǎng)景。

但是,如果我們?yōu)榱遂偶级环謭?chǎng)合濫用CopyOnWriteArrayList的話,可能會(huì)帶來(lái)適得其反的結(jié)果。

下面,我們通過(guò)一段測(cè)試代碼,比較一下CopyOnWriteArrayList和普通加鎖ArrayList的讀寫(xiě)性能差距。

我們首先測(cè)試一下寫(xiě)性能的差距:構(gòu)建一個(gè)CopyOnWriteArrayList和synchronizedList,通過(guò)多線程并發(fā)寫(xiě)入100000個(gè)元素。

List copyOnWriteArrayList = new CopyOnWriteArrayList<>();
//構(gòu)建一個(gè)加鎖的List
List synchronizedList = Collections.synchronizedList(new ArrayList<>());
StopWatch stopWatch = new StopWatch();
int loopCount = 100000;
stopWatch.start("測(cè)試寫(xiě)性能:copyOnWriteArrayList");
//多線程寫(xiě)入100000個(gè)數(shù)字
IntStream.rangeClosed(1, loopCount).parallel()
.forEach(x -> copyOnWriteArrayList.add(ThreadLocalRandom.current().nextInt(loopCount))
);
stopWatch.stop();
stopWatch.start("測(cè)試寫(xiě)性能:synchronizedList");
//多線程寫(xiě)入100000個(gè)數(shù)字
IntStream.rangeClosed(1, loopCount).parallel()
.forEach(x -> synchronizedList.add(ThreadLocalRandom.current().nextInt(loopCount))
);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
Map result = new HashMap<>();
result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
result.put("synchronizedList", synchronizedList.size());
System.out.println(JSON.toJSONString(result));

可以清楚的看到,在大量寫(xiě)的情況下,CopyOnWriteArrayList的性能是遠(yuǎn)遠(yuǎn)不如普通的加鎖List的,性能差距可能在100倍以上。

而之所以CopyOnWriteArrayList的寫(xiě)入這么慢,就是因?yàn)镃opyOnWriteArrayList每次寫(xiě)入都要對(duì)存放元素的舊數(shù)組進(jìn)行復(fù)制創(chuàng)建一個(gè)新數(shù)組,從而導(dǎo)致內(nèi)存申請(qǐng)釋放消耗很大。

我們?cè)贉y(cè)試一下大量讀的性能差距:先對(duì)兩個(gè)List寫(xiě)入100000個(gè)元素,再通過(guò)多線程的方式隨機(jī)get元素。

List synchronizedList = Collections.synchronizedList(new ArrayList<>());
synchronizedList.addAll(IntStream.rangeClosed(1, 100000).boxed().collect(Collectors.toList()));

List copyOnWriteArrayList = IntStream.rangeClosed(1, 100000).boxed()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));

StopWatch stopWatch = new StopWatch();
int loopCount = 1000000;
int count = copyOnWriteArrayList.size();
stopWatch.start("測(cè)試讀性能:copyOnWriteArrayList");
IntStream.rangeClosed(1, loopCount).parallel().forEach(
x -> copyOnWriteArrayList.get(ThreadLocalRandom.current().nextInt(count))
);
stopWatch.stop();
stopWatch.start("測(cè)試讀性能:synchronizedList");
IntStream.range(0, loopCount).parallel().forEach(
x -> synchronizedList.get(ThreadLocalRandom.current().nextInt(count))
);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
Map result = new HashMap<>();
result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
result.put("synchronizedList", synchronizedList.size());
System.out.println(JSON.toJSONString(result));

經(jīng)過(guò)多次測(cè)試,CopyOnWriteArrayList的讀性能大概在普通加鎖List的2-5倍左右。

而CopyOnWriteArrayList的讀之所以快,是因?yàn)镃opyOnWriteArrayList讀取元素是無(wú)鎖狀態(tài)下直接按數(shù)組下標(biāo)獲取。

一般來(lái)說(shuō),CopyOnWriteArrayList只適用于大量讀的場(chǎng)景,如果有了大量寫(xiě)操作,性能反而不如普通的List。

JDK為我們提供了很多用于并發(fā)場(chǎng)景的工具類,但是仍需要我們仔細(xì)了解每一種工具的使用場(chǎng)景,在不合適的場(chǎng)景使用不合適的工具,會(huì)導(dǎo)致性能更差。


文章名稱:不要在線上濫用CopyOnWriteArrayList,姿勢(shì)不對(duì)性能真的很糟糕
分享URL:http://m.5511xx.com/article/cdschgs.html