成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

并發與高并發系列第一集-基礎與概念

開發 架構
通常我們談論并發的時候,更多的關注點在于線程安全,但是討論高并發時,關注點不僅僅是線程安全問題,而是如何在短時間內處理大量請求,保證系統響應時間和吞吐量的可靠,更多關注的是穩定性問題(SRE),高并發涉及的是完整的系統知識,線程安全只是其中一小部分。

[[404291]]

本文轉載自微信公眾號「安琪拉的博客」,作者安琪拉。轉載本文請聯系安琪拉的博客公眾號。

面試官:看你簡歷上寫,最近正在寫并發編程方面的博客,是吧?

安琪拉:閑來無事,看看閑書,寫寫段子,承蒙讀者厚愛,有此打算。

面試官:少跟我這拽文,“閑來無事”?阿里不用996嗎?

安琪拉:修福報,你知道嗎?..... 技術人的日常,能算996嗎?

面試官:算了算了,還是聊正題,你先跟我講講什么是并發?

安琪拉:并發就是存在兩個或多個線程,這些線程同時操作相同的物理機中的資源。

面試官:那并發跟并行有什么區別呢?

安琪拉:舉個生活中的例子就懂了:

你在打王者榮耀,這個時候女朋友找你視頻,你一直打完王者榮耀才接,說明你不支持并發(也不支持并行);

你在打王者榮耀,這個時候女朋友給你發了微信,你退出王者榮耀,回完微信再回到王者,微信和王者間來回切換,說明你支持并發,但不支持并行;

你在打王者榮耀,這個時候女朋友給你打電話,你邊打榮耀邊接電話,說明你支持并行。

并行的關鍵點是物理的“同時”,我們在單核CPU的時候,既能寫代碼也能聽歌,這個多線程實際是基于操作系統根據CPU時間片做的任務輪轉,是偽“同時”,只能說是并發,不能算并行,但是多核CPU可以支持每個核同時運行任務,是真實的“同時”,是并行。

Erlang 之父 Joe Armstrong 畫了一張圖解釋了并發與并行的區別,Concurrent (并發),Parallel (并行)。

并發允許二隊小孩輪流使用咖啡機,并行是同時存在二臺咖啡機,二隊小孩同時使用,不沖突。

面試官:那高并發呢?你了解高并發嗎?

安琪拉:【心里想,該來的還是來了,要造火箭了】

你說High Concurrency(高并發)是吧(先拽句英文)。

通常我們談論并發的時候,更多的關注點在于線程安全,但是討論高并發時,關注點不僅僅是線程安全問題,而是如何在短時間內處理大量請求,保證系統響應時間和吞吐量的可靠,更多關注的是穩定性問題(SRE),高并發涉及的是完整的系統知識,線程安全只是其中一小部分。

高并發是現在互聯網設計系統中需要考慮的一個重要因素之一,通常來說,就是通過嚴謹的設計來保證系統能夠同時并行處理很多的請求。這就是大家常說的「 高并發 」。也就是說系統能夠在某一時間段內提供很多請求,但是不會影響系統的性能。如果想設計出高可用和高性能的系統,就應該從很多的方面來考慮,例如應該從硬件、軟件、編程語言的選擇、網絡方面的考慮、系統的整體架構、數據結構、算法的優化、數據庫的優化等等多方面。這其中的每一點展開來說都要說很多的知識,安琪拉會在后續課程更新這部分內容。

面試官:那你跟我講講你們系統的QPS有多少?

安琪拉:大促場景能有個10W+的QPS,日常業務高峰期也有2W+,其他時間幾千。

其實對于大部分的系統,幾十、幾百很正常,QPS能過千的就已經不低了,有的業務會有峰值,QPS穩定過萬的系統實際中不多,所以大家日常可以關注一下自己系統的QPS,這個問題面試經常會問。

面試官:一般我們有什么工具可以模擬并發請求呢?

安琪拉:PostMan、Apache Bench(AB)、Jmeter,推薦使用Jmeter。

面試官:那你能寫段代碼,演示一下并發安全的問題嗎?

安琪拉:可以啊。筆遞給我一下,順便幫我拿下A4紙。

  1. public class ConcurrencySafeTest { 
  2.  
  3.     private static int counter = 0; 
  4.  
  5.     public static void main(String[] args) { 
  6.         //使用線程池 
  7.         ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 
  8.         //提交2000個任務 
  9.         for(int i = 0; i < 2000; i++) { 
  10.             threadPool.submit(new Add()); 
  11.         } 
  12.         threadPool.shutdown(); 
  13.         System.out.println(counter); 
  14.     } 
  15.  
  16.     static class Add implements Runnable { 
  17.         @Override 
  18.         public void run() { 
  19.             counter++; 
  20.         } 
  21.     } 

我們進行計數操作,執行2000次,預期的執行結果應該是2000,但是實際執行結果如下:

  1. 1971 
  2. 1987 

因為《并發》系列是從基礎開始講的,上面的代碼部分內容涉及到后面的一些內容,比如線程池和線程的使用,這里只要大致了解并發的安全問題,后面會有詳細說明,后面面試官的問題作為擴展閱讀。

面試官:看到你代碼中用了CachedThreadPool,那2000次任務執行,CachedThreadPool 線程池創建了多少個線程?

安琪拉:答案是不確定,CachedThreadPool 緩存了線程(復用線程),沒有讓任務排隊,來一個任務,要么復用已有線程處理,要么新建一個線程處理。那我們怎么確定線程池創建過多少個線程呢?可以加一段代碼打印出來。

如下:

  1. private static int counter = 0; 
  2.  
  3. public static void main(String[] args) { 
  4. //使用線程池 
  5. ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 
  6. //提交2000個任務 
  7. for(int i = 0; i < 2000; i++) { 
  8. threadPool.submit(new Add()); 
  9. threadPool.shutdown(); 
  10. //打印最多使用線程數 
  11. System.out.println("largestPoolSize:" + threadPool.getLargestPoolSize()); 
  12. System.out.println(counter); 

輸出結果如下:

  1. 第一次: 
  2. largestPoolSize:11 
  3. 1937 
  4. 第一次: 
  5. largestPoolSize:14 
  6. 1956 
  7. 第一次: 
  8. largestPoolSize:31 
  9. 1970 

可以看到每次都不一樣,線程池之前有文章講過,這個系列后面還會深入講解。

關于 largestPoolSize, 注釋說明了,記錄線程池中最大的線程數。

  1. /** 
  2. * Tracks largest attained pool size. Accessed only under 
  3. * mainLock. 
  4. */ 
  5. private int largestPoolSize; 

面試官:看你代碼中寫了調用線程池的shutdown,那shutdown 和 shutdownNow 方法什么區別?

安琪拉:shutdown 是將線程池的狀態設置為SHUTWDOWN狀態,正在執行的任務會繼續執行下去,沒有被執行的則中斷。而shutdownNow則是將線程池的狀態設置為STOP,正在執行的任務則被停止,沒被執行任務的則返回。

源碼對比:

  1. //shutdown 
  2. public void shutdown() { 
  3.   final ReentrantLock mainLock = this.mainLock; 
  4.   mainLock.lock(); 
  5.   try { 
  6.     checkShutdownAccess(); 
  7.     //設置線程池狀態為SHUTDOWN 
  8.     advanceRunState(SHUTDOWN); 
  9.     interruptIdleWorkers(); 
  10.     onShutdown(); // hook for ScheduledThreadPoolExecutor 
  11.   } finally { 
  12.     mainLock.unlock(); 
  13.   } 
  14.   tryTerminate(); 
  1. public List<Runnable> shutdownNow() { 
  2.   List<Runnable> tasks; 
  3.   final ReentrantLock mainLock = this.mainLock; 
  4.   mainLock.lock(); 
  5.   try { 
  6.     checkShutdownAccess(); 
  7.     //設置線程池狀態為STOP 
  8.     advanceRunState(STOP); 
  9.     interruptWorkers(); 
  10.     //把隊列剩余等待執行任務取出,返回 
  11.     tasks = drainQueue(); 
  12.   } finally { 
  13.     mainLock.unlock(); 
  14.   } 
  15.   tryTerminate(); 
  16.   return tasks; 

面試官:線程池有哪幾種狀態?

安琪拉:5種,注意這里說的是線程池的狀態,不是線程的狀態。下面是線程池的狀態流轉圖:

本文是《并發》系列第一集,主要介紹了一些并發、并行、高并發的一些基礎概念,以及并發安全問題的案例,下一集講并發的風險與優勢和CPU多級緩存,以及一些內存操作的指令,然后說Java內存模型。

完整大綱參考:

 

責任編輯:武曉燕 來源: 安琪拉的博客
相關推薦

2021-12-08 15:09:26

鴻蒙HarmonyOS應用

2021-06-11 07:30:30

并發高并發內存

2013-04-25 14:05:20

Windows PhoWindows PhoWindows Pho

2021-07-03 17:44:34

并發高并發原子性

2023-09-13 06:49:05

克隆內測版Illmind

2020-08-18 13:50:04

Tomcat高并發Java

2019-06-28 10:55:04

預熱高并發并發高

2021-02-26 13:08:27

Java高并發AQS

2023-07-06 08:06:47

LockCondition公平鎖

2020-09-03 14:30:40

Tomcat 拆解調優

2021-04-28 08:52:22

高并發架構設高并發系統

2009-11-25 11:20:31

并發

2019-09-16 09:23:34

高并發編程CountDownLaCyclicBarri

2021-04-28 08:00:16

多線程高并發操作

2023-12-08 18:01:25

Java關鍵字

2013-07-17 17:03:23

Ngx_luaNginx

2014-12-25 09:47:59

GuavaGuava并發

2021-07-30 07:28:15

WorkerPoolGo語言

2025-03-10 10:00:00

Ollama高并發

2011-11-30 12:32:38

企業防毒防毒方案拯救三
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久免费资源 | 国产精品成人免费 | 人人干人人干人人 | 成人亚洲综合 | 欧美一级欧美一级在线播放 | 夜夜精品浪潮av一区二区三区 | 亚洲手机视频在线 | 在线日韩欧美 | 韩日av片| 欧美99| 成人毛片网站 | 亚洲成人精品 | 激情三区 | 国产日韩精品一区 | 国产黄色在线观看 | 国产精品99久久久久久人 | 亚洲国产欧美一区二区三区久久 | 亚洲永久 | 九九九国产 | 亚洲一区三区在线观看 | 久久男人 | 51ⅴ精品国产91久久久久久 | 亚洲精品欧美精品 | www.精品国产| 欧洲国产精品视频 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 日韩三级电影在线看 | 免费的色网站 | 狠狠操天天操 | 国产在线麻豆精品入口 | 狠狠久| 人人射人人插 | 亚洲精品欧美 | 亚洲精品久久久久久国产精华液 | 青青久在线视频 | 精品九九 | 久久精品国产免费看久久精品 | a级片播放 | 香蕉视频久久久 | 国产在线精品一区二区 | 91精品国产综合久久小仙女图片 |