精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

在線求CR,你覺得我這段Java代碼還有優化的空間嗎?

開發 后端
先說一下背景,也就是要知道我們單元測試要測的這個方法具體是什么樣的功能。我們要測試的服務是AssetService,被測試的方法是update方法。

[[409316]]

 上周,因為要測試一個方法的在并發場景下的結果是不是符合預期,我寫了一段單元測試的代碼。寫完之后截了個圖發了一個朋友圈,很多人表示短短的幾行代碼,涉及到好幾個知識點。

還有人給出了一些優化的建議。那么,這是怎樣的一段代碼呢?涉及到哪些知識,又有哪些可以優化的點呢?

讓我們來看一下。

背景

先說一下背景,也就是要知道我們單元測試要測的這個方法具體是什么樣的功能。我們要測試的服務是AssetService,被測試的方法是update方法。

update方法主要做兩件事,第一個是更新Asset、第二個是插入一條AssetStream。

更新Asset方法中,主要是更新數據庫中的Asset的信息,這里為了防止并發,使用了樂觀鎖。

插入AssetStream方法中,主要是插入一條AssetStream的流水信息,為了防止并發,這里在數據庫中增加了唯一性約束。

為了保證數據一致性,我們通過本地事務將這兩個操作包在同一個事務中。

以下是主要的代碼,當然,這個方法中還會有一些前置的冪等性校驗、參數合法性校驗等,這里就都省略了: 

  1. @Service  
  2. public class AssetServiceImpl implements AssetService {  
  3.     @Autowired  
  4.     private TransactionTemplate transactionTemplate;  
  5.     @Override  
  6.     public String update(Asset asset) {  
  7.         //參數檢查、冪等校驗、從數據庫取出最新asset等。  
  8.         return transactionTemplate.execute(status -> {  
  9.             updateAsset(asset);  
  10.             return insertAssetStream(asset);  
  11.         });  
  12.     }  

因為這個方法可能會在并發場景中執行,所以該方法通過事務+樂觀鎖+唯一性約束做了并發控制。關于這部分的細節就不多講了,大家感興趣的話后面我再展開關于如何防并發的內容。

單測

因為上面這個方法是可能在并發場景中被調用的,所以需要在單測中模擬并發場景,于是,我就寫了以下的單元測試的代碼: 

  1. public class AssetServiceImplTest {  
  2.     private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()  
  3.         .setNameFormat("demo-pool-%d").build();  
  4.     private static ExecutorService pool = new ThreadPoolExecutor(20, 100,  
  5.         0L, TimeUnit.MILLISECONDS,  
  6.         new LinkedBlockingQueue<Runnable>(128), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());  
  7.     @Autowired  
  8.     private AssetService assetService;  
  9.     @Test 
  10.      public void test_updateConcurrent() {  
  11.         Asset asset = getAsset();  
  12.         //參數的準備  
  13.         //... 
  14.          //并發場景模擬  
  15.         CountDownLatch countDownLatch = new CountDownLatch(10);  
  16.         AtomicInteger atomicInteger =new AtomicInteger();          
  17.          //并發批量修改,只有一條可以修改成功  
  18.         for (int i = 0; i < 10; i++) {  
  19.             pool.execute(() -> {  
  20.                 try {  
  21.                     String streamNo = assetService.update(asset);  
  22.                 } catch (Exception e) { 
  23.                      System.out.println("Error : " + e);  
  24.                     failedCount.getAndIncrement();  
  25.                 } finally {  
  26.                     countDownLatch.countDown();  
  27.                 }  
  28.             });  
  29.         }  
  30.         try {  
  31.             //主線程等子線程都執行完之后查詢最新的資產  
  32.             countDownLatch.await();  
  33.         } catch (InterruptedException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.         Assert.assertEquals(failedCount.intValue(), 9);  
  37.         // 從數據庫中反查出最新的Asset  
  38.         // 再對關鍵字段做注意校驗  
  39.     }  

以上,就是我做了簡化之后的單元測試的部分代碼。因為要測并發場景,所以這里面涉及到了很多并發相關的知識。

很多人之前和我說,并發相關的知識自己了解的很多,但是好像沒什么機會寫并發的代碼。其實,單元測試就是個很好的機會。

我們來看看上面的代碼涉及到哪些知識點?

知識點

以上這段單元測試的代碼中涉及到幾個知識點,我這里簡單說一下。

線程池

這里面因為要模擬并發的場景,所以需要用到多線程, 所以我這里使用了線程池,而且我沒有直接用Java提供的Executors類創建線程池。

而是使用guava提供的ThreadFactoryBuilder來創建線程池,使用這種方式創建線程時,不僅可以避免OOM的問題,還可以自定義線程名稱,更加方便的出錯的時候溯源。(關于線程池創建的OOM問題)

CountDownLatch

因為我的單元測試代碼中,希望在所有的子線程都執行之后,主線程再去檢查執行結果。

所以,如何使主線程阻塞,直到所有子線程執行完呢?這里面用到了一個同步輔助類CountDownLatch。

用給定的計數初始化 CountDownLatch。由于調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。

AtomicInteger

因為我在單測代碼中,創建了10個線程,但是我需要保證只有一個線程可以執行成功。所以,我需要對失敗的次數做統計。

那么,如何在并發場景中做計數統計呢,這里用到了AtomicInteger,這是一個原子操作類,可以提供線程安全的操作方法。

異常處理

因為我們模擬了多個線程并發執行,那么就一定會存在部分線程執行失敗的情況。

因為方法底層沒有對異常進行捕獲。所以需要在單測代碼中進行異常的捕獲。 

  1. try {  
  2.       String streamNo = assetService.update(asset);  
  3.   } catch (Exception e) {  
  4.       System.out.println("Error : " + e);  
  5.       failedCount.increment();  
  6.   } finally {  
  7.       countDownLatch.countDown();  
  8.   } 

這段代碼中,try、catch、finall都用上了,而且位置是不能調換的。失敗次數的統計一定要放到catch中,countDownLatch的countDown也一定要放到finally中。

Assert

這個相信大家都比較熟悉,這就是JUnit中提供的斷言工具類,在單元測試時可以用做斷言。這就不詳細介紹了。

優化點

以上代碼涉及到了很多知識點,但是,難道就沒有什么優化點了嗎?

首先說一下,其實單元測試的代碼對性能、穩定性之類的要求并不高,所謂的優化點,也并不是必要的。這里只是說討論下,如果真的是要做到精益求精,還有什么點可以優化呢?

使用LongAdder代替AtomicInteger

我的朋友圈的網友@zkx 提出,可以使用LongAdder代替AtomicInteger。

java.util.concurrency.atomic.LongAdder是Java8新增的一個類,提供了原子累計值的方法。而且在其Javadoc中也明確指出其性能要優于AtomicLong。

首先它有一個基礎的值base,在發生競爭的情況下,會有一個Cell數組用于將不同線程的操作離散到不同的節點上去(會根據需要擴容,最大為CPU核數,即最大同時執行線程數),sum()會將所有Cell數組中的value和base累加作為返回值。

核心的思想就是將AtomicLong一個value的更新壓力分散到多個value中去,從而降低更新熱點。所以在激烈的鎖競爭場景下,LongAdder性能更好。

增加并發競爭

朋友圈網友 @Cafebabe 和 @普渡眾生的面癱青年 以及 @嘉俊 ,都提到同一個優化點,那就是如何增加并發競爭。

這個問題其實我在發朋友圈之前就有想到過,心中早已經有了答案,只不過有多位朋友能夠幾乎同時提到這一點還是很不錯的。

我們來說說問題是什么。

我們為了提升并發,使用線程池創建了多個線程,想讓多個線程并發執行被測試的方法。

但是,我們是在for循環中依次執行的,那么理論上這10次update方法的調用是順序執行的。

當然,因為有CPU時間片的存在,這10個線程會爭搶CPU,真正執行的過程中還是會發生并發沖突的。

但是,為了穩妥起見,我們還是需要盡量模擬出多個線程同時發起方法調用的。

優化的方法也比較簡單,那就是在每一個update方法被調用之前都wait一下,直到所有的子線程都創建成功了,再開始一起執行。

這里就可以用到CyclicBarrier來實現,CyclicBarrier和CountDownLatch一樣,都是關于線程的計數器。

CountDownLatch: 一個線程(或者多個), 等待另外N個線程完成某個事情之后才能執行。 

CyclicBrrier: N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。

所以,最終優化后的單測代碼如下: 

  1. //主線程根據此CountDownLatch阻塞  
  2. CountDownLatch mainThreadHolder = new CountDownLatch(10);  
  3. //并發的多個子線程根據此CyclicBarrier阻塞  
  4. CyclicBarrier cyclicBarrier = new CyclicBarrier(10);  
  5. //失敗次數計數器  
  6. LongAdder failedCount = new LongAdder();  
  7. //并發批量修改,只有一條可以修改成功  
  8. for (int i = 0; i < 10; i++) {  
  9.     pool.execute(() -> {  
  10.         try {  
  11.             //子線程等待,所有線程就緒后開始執行  
  12.             cyclicBarrier.await();  
  13.             //調用被測試的方法  
  14.             String streamNo = assetService.update(asset);  
  15.         } catch (Exception e) {  
  16.             //異常發生時,對失敗計數器+1  
  17.             System.out.println("Error : " + e);  
  18.             failedCount.increment();  
  19.         } finally {  
  20.             //主線程的阻塞器奇數-1  
  21.             mainThreadHolder.countDown();  
  22.         }  
  23.     });  
  24.  
  25. try {  
  26.     //主線程等子線程都執行完之后查詢最新的資產池計劃  
  27.     mainThreadHolder.await();  
  28. } catch (InterruptedException e) {  
  29.     e.printStackTrace();  
  30.  
  31. //斷言,保證失敗9次,則成功一次  
  32. Assert.assertEquals(failedCount.intValue(), 9); 
  33. // 從數據庫中反查出最新的Asset  
  34. // 再對關鍵字段做注意校驗 

以上,就是關于我的一次單元測試的代碼所涉及到的知識點,以及目前所能想到的相關的優化點。 

 

責任編輯:龐桂玉 來源: Hollis
相關推薦

2022-12-08 17:32:25

chatGPT人工智能聊天

2021-08-31 10:52:30

容量背包物品

2023-08-10 13:57:50

模型AI

2022-10-09 09:38:10

高可用設計

2016-01-21 09:55:51

2017-11-01 15:09:26

字體Android技術

2012-06-18 15:18:32

JS

2023-04-14 10:40:45

工具編譯器優化

2021-09-17 08:04:28

Hooks函數組件架構

2021-01-04 14:21:21

人工智能機器學習語言

2020-08-24 07:18:28

手機監聽Facebook

2020-09-04 15:05:50

GitHub代碼空間特定倉庫

2014-01-17 14:39:18

12306 搶票

2020-04-20 13:43:59

黑客聯網攻擊

2021-04-27 06:44:03

PythonCython編程語言

2012-11-19 14:29:38

JavaJava異常異常處理

2021-08-10 10:48:39

拷貝代碼架構耦合

2021-01-29 08:09:32

Service接口表現層

2022-12-08 19:20:11

開源用戶使用軟件

2012-04-01 10:47:47

點贊
收藏

51CTO技術棧公眾號

亚洲免费伊人电影| 巨乳诱惑日韩免费av| 欧美一区二区三区视频免费| 青青视频免费在线观看| 人妻中文字幕一区| 日本伊人精品一区二区三区观看方式| 日韩一级黄色av| 国产清纯白嫩初高中在线观看性色| 丝袜老师在线| 中文字幕在线不卡一区二区三区| 91精品久久久久久蜜桃| 精品成人久久久| 久久精品国产99久久| 亚洲国产天堂久久综合| 欧美一级特黄a| 超碰在线网站| 国产精品蜜臀在线观看| 国产一级二级三级精品| 亚洲最大成人av| 在线一区视频| 九九热精品视频| av电影在线不卡| 国产精品网在线观看| 欧美日韩你懂得| 国产第一页视频| 日本不卡影院| 最近中文字幕一区二区三区| 久久综合色一本| www.中文字幕| 精品一区二区三区影院在线午夜| 2019中文字幕在线免费观看| 五月天丁香激情| 久久裸体网站| 国产亚洲xxx| 欧美做受喷浆在线观看| 亚洲开心激情| 亚洲天堂一区在线| 在线日韩电影| 欧美激情成人在线视频| 影音先锋男人资源在线观看| 狠狠色狠狠色综合婷婷tag| 亚洲国产成人av在线| 少妇欧美激情一区二区三区| 久久三级毛片| 欧美天堂一区二区三区| 国产综合免费视频| 日本在线影院| 亚洲aⅴ怡春院| 性一交一乱一伧国产女士spa| 韩国中文字幕在线| 亚洲欧洲av在线| 色香蕉在线观看| 欧美激情办公室videoshd| 欧美—级在线免费片| 日本在线观看一区二区三区| 欧美3p视频在线观看| 99久久99久久免费精品蜜臀| 精品欧美一区二区三区久久久| 亚洲va天堂va欧美ⅴa在线| 国产乱码精品一区二区三区五月婷 | 精品日韩欧美一区| 亚洲亚裔videos黑人hd| 真实乱视频国产免费观看| 欧美日本成人| 在线丨暗呦小u女国产精品| 成人在线一级片| 成人aaaa| 久久综合五月天| 在线观看成人毛片| 亚洲经典三级| 国产97免费视| 亚洲手机在线观看| 国产精品88av| 国产在线精品一区二区三区| 午夜视频www| 国产亚洲一区二区在线观看| 色综合666| 久操视频在线观看| 亚洲第一主播视频| 日韩欧美精品在线观看视频| 日本美女久久| 日韩一区二区三区精品视频| 欧美一区二区三区影院| 免费国产a级片| 超碰免费公开在线| 亚洲图片欧美视频| 久草青青在线观看| 国产91在线播放精品| 欧美高清你懂得| 亚洲乱妇老熟女爽到高潮的片| 欧美亚洲tv| 伊人久久综合97精品| 日韩影院一区二区| 99视频在线精品国自产拍免费观看| 欧美在线视频一区二区| 在线观看国产成人| 成人黄色一级视频| 色综合666| 波多野结衣在线播放| 欧美亚洲综合色| 人妻少妇偷人精品久久久任期| 欧美日韩夜夜| 久久精品99久久久久久久久| 日韩高清精品免费观看| 另类欧美日韩国产在线| 国产综合18久久久久久| √新版天堂资源在线资源| 亚洲夂夂婷婷色拍ww47| 国产一级做a爰片久久| 99久久人爽人人添人人澡| 国产亚洲欧洲高清一区| 国产真实的和子乱拍在线观看| 日韩激情视频在线观看| 国产精品yjizz| 免费黄网在线观看| 色综合欧美在线视频区| 色婷婷狠狠18禁久久| 第一社区sis001原创亚洲| 久久久免费观看视频| 国产又粗又猛又色又| 久久精品人人做人人综合| 男人添女荫道口喷水视频| 日韩成人综合网站| 国产婷婷色综合av蜜臀av| 久久精品www| 狠狠色丁香久久婷婷综合_中 | 99草在线视频| 国产丝袜美腿一区二区三区| av在线播放天堂| 91麻豆精品国产综合久久久| 亚洲四色影视在线观看| 国产性xxxx高清| 国产精品正在播放| 青春草在线视频免费观看| 欧美va在线观看| 亚洲欧美日韩爽爽影院| 国产毛片aaa| 成人黄色大片在线观看| 国产在线无码精品| 亚洲精品无播放器在线播放| 国产亚洲美女精品久久久| 99久久久久久久久| 26uuu国产一区二区三区| 福利视频一区二区三区四区| 午夜免费欧美电影| 欧美成人免费全部观看天天性色| 国产精品无码AV| 日韩美女啊v在线免费观看| 天天爽夜夜爽一区二区三区| 欧美日韩国产高清电影| 国产精品成人av性教育| 黄色片免费在线| 在线看国产一区| www久久久久久久| 免费的成人av| 中国人体摄影一区二区三区| 偷拍自拍亚洲| 美日韩精品免费观看视频| 91亚洲国产成人精品一区| 亚洲色图制服丝袜| 少妇愉情理伦片bd| 欧美视频日韩| 狠狠色综合色区| 亚洲精品mv| 中文字幕免费精品一区| 亚洲字幕av一区二区三区四区| 亚洲日韩欧美一区二区在线| 女教师高潮黄又色视频| 99精品视频网| 欧美影视一区二区| 免费视频成人| 欧美成人精品激情在线观看| 亚洲精品综合网| 欧美视频不卡中文| 国产一区二区三区四区在线| 麻豆精品精品国产自在97香蕉| 艳母动漫在线观看| 女一区二区三区| 国产精品吊钟奶在线| 快射视频在线观看| 精品国一区二区三区| 成人午夜淫片100集| 日本一区二区三区在线不卡| 国产精品嫩草影院8vv8| 欧美视频亚洲视频| 秋霞在线观看一区二区三区| 欧美成a人片免费观看久久五月天| 久久精品久久久久久| 秋霞视频一区二区| 在线观看av一区| 777777国产7777777| 成人av电影在线观看| 成年人在线观看视频免费| 亚洲精品成人| 欧美精品一区二区三区久久| 精品视频成人| 7777免费精品视频| 欧美尤物美女在线| 亚洲黄色片网站| 91亚洲视频在线观看| 大荫蒂欧美视频另类xxxx| 激情高潮到大叫狂喷水| 成人一区二区三区| www.这里只有精品| 在线亚洲欧美| 欧美 日韩 国产精品| 欧美三级伦理在线| 精品中文字幕人| 日本超碰一区二区| 国产成人综合av| 青青青免费在线视频| 久久国产精品网站| 69视频在线| 亚洲色图25p| 亚洲av成人精品一区二区三区在线播放 | 亚洲一级在线播放| 精品动漫一区二区三区| 亚洲国产精品久| 国产精品久久久久7777按摩| 国产精品jizz| 成人av免费在线观看| 中文字幕一二三区| 韩国一区二区在线观看| 玩弄japan白嫩少妇hd| 亚洲黑丝一区二区| 黄色片免费在线观看视频| 欧美成人激情| 亚洲高清精品中出| 国产精品入口久久| 免费试看一区| 日日天天久久| 国内精品二区| 玖玖玖免费嫩草在线影院一区| 亚洲最大福利网站| 国产精品高清一区二区| 国产欧美日韩91| 日韩久久一区| 国产三级精品网站| 久久久久黄色| 国产精品一区二区久久国产| 91另类视频| 国产精品视频自拍| 97成人超碰| 国产精品美乳在线观看| 久久av日韩| 成人天堂噜噜噜| 97久久中文字幕| 亚洲一区制服诱惑| 在这里有精品| 国产精成人品localhost| jizz国产精品| 国产伦精品一区二区三区照片| 超碰一区二区三区| 国产精品视频免费观看| 日本欧美高清| 日韩国产伦理| 久久影院一区| 特大黑人娇小亚洲女mp4| 女人天堂亚洲aⅴ在线观看| 久久国产精品免费观看| 亚洲一级特黄| 欧美日韩激情视频在线观看| 免费在线观看成人av| 又色又爽又高潮免费视频国产| 免费观看成人av| 精品国产午夜福利在线观看| 成人av网址在线| asian性开放少妇pics| 国产欧美在线观看一区| 很污很黄的网站| 亚洲国产精品一区二区www在线| 日韩欧美不卡视频| 在线亚洲+欧美+日本专区| 亚洲系列在线观看| 精品日韩99亚洲| 日本视频在线观看一区二区三区| 永久免费看mv网站入口亚洲| gogogogo高清视频在线| 97香蕉久久夜色精品国产| 国产经典一区| 亚洲xxx视频| 亚州综合一区| 欧美aaa在线观看| 日韩一级在线| 一道本视频在线观看| 国产iv一区二区三区| 国精产品一区一区三区免费视频| 国产精品第一页第二页第三页| 久久精品一区二区三| 欧美影院午夜播放| 免费a级片在线观看| 中文字幕av一区二区| 2021天堂中文幕一二区在线观| 国产精品久久不能| 91国内精品白嫩初高生| 图片区小说区区亚洲五月| 欧美日韩精选| 性刺激的欧美三级视频| av欧美精品.com| 五月婷婷综合激情网| 精品国产1区2区| 91精品人妻一区二区三区果冻| 精品久久久久av影院| 日本电影在线观看网站| 性欧美xxxx视频在线观看| 亚洲精品伦理| 欧美精彩一区二区三区| 欧美私人啪啪vps| 国产高清视频网站| 97精品久久久午夜一区二区三区 | 国产精品久久久久久亚洲调教| 午夜精品在线| 在线观看日本一区| 丝袜美腿亚洲一区二区图片| 精品人妻一区二区免费| 国产精品白丝在线| 神马久久久久久久| 亚洲成色777777女色窝| 黄色免费在线观看网站| 国产精品久久久久久久av电影| 国产精品调教视频| 久久久久久久久久久综合| 久久丁香综合五月国产三级网站| 精品人妻无码一区二区三区| 亚洲国产精品一区二区www | xxxxx.日韩| 久久99精品久久久久久秒播放器| 国产一区二区三区自拍| 亚洲精品国产久| 中文字幕在线观看不卡| 中文字幕久久久久| 在线观看视频99| 日韩av免费| 日本一区高清在线视频| 日韩午夜一区| av无码一区二区三区| 亚洲国产精品一区二区www| 亚洲精品一区二区三区区别| 欧美富婆性猛交| 亚洲1区在线观看| 亚洲高潮无码久久| 国产麻豆日韩欧美久久| 亚洲最大的黄色网址| 制服丝袜亚洲色图| 国产在线高清理伦片a| 91精品国产综合久久久久久久久| 日韩欧美一区二区三区免费看| 男女视频在线看| 国产精品九色蝌蚪自拍| 国产精品高潮呻吟AV无码| 少妇精69xxtheporn| 久久精品97| 中文字幕精品在线播放 | 国产精品扒开腿做爽爽| 午夜精品成人在线| 手机福利小视频在线播放| 2023亚洲男人天堂| 九一精品国产| 手机看片福利日韩| 国产精品成人一区二区艾草 | 特级毛片www| 亚洲深夜福利网站| 国产精品伊人| 大桥未久一区二区三区| 成人免费高清在线| 国产香蕉视频在线| 亚洲香蕉在线观看| 日本午夜精品久久久久| 粉嫩av一区二区三区天美传媒| 国产成人在线影院| 国产视频91在线| 中文字幕欧美亚洲| 秋霞影院一区| 丰满少妇被猛烈进入高清播放| 国产欧美日韩视频一区二区| 97免费观看视频| 97超级碰碰碰久久久| 精品久久91| 成人做爰69片免费| 91国产丝袜在线播放| 黄色精品免费看| 精品视频在线观看| 老司机午夜精品| 久久免费视频播放| 亚洲亚裔videos黑人hd| 久久天堂久久| 国产第一页视频| 亚洲永久精品大片| 国内在线精品| http;//www.99re视频| 久久婷婷一区| 欧美日韩免费做爰视频| 日韩精品一二三四区| 日韩国产91| 欧美网站免费观看| 亚洲人精品一区| 国产视频第一区| 北条麻妃高清一区| 久久国产精品区| 无码aⅴ精品一区二区三区|