高併發(High Concurrency)是一種系統運行過程當中遇到的一種「短期內遇到大量操做請求」的狀況,主要發生在web系統集中大量訪問收到大量請求(例如:12306的搶票狀況;天貓雙十一活動)。該狀況的發生會致使系統在這段時間內執行大量操做,例如對資源的請求、數據庫的操做等。mysql
高併發相關經常使用的一些指標有:響應時間、吞吐量、每秒查詢率QPS、併發用戶數
一、響應時間(Response Time)web
響應時間:系統對請求作出響應的時間。例如系統處理一個HTTP請求須要200ms,這個200ms就是系統的響應時間redis
二、吞吐量(Throughput)算法
吞吐量:單位時間內處理的請求數量。sql
三、每秒查詢率QPS(Query Per Second)數據庫
QPS:每秒響應請求數。在互聯網領域,這個指標和吞吐量區分的沒有這麼明顯。編程
四、併發用戶數緩存
併發用戶數:同時承載正常使用系統功能的用戶數量。例如一個即時通信系統,同時在線量必定程度上表明瞭系統的併發用戶數。網絡
「高併發和多線程」老是被一塊兒提起,給人感受二者好像相等,實則 高併發 ≠ 多線程數據結構
多線程是Java的特性,由於如今cpu都是多核多線程的,能夠同時執行幾個任務,爲了提升jvm的執行效率,Java提供了這種多線程的機制,以加強數據處理效率。多線程對應的是cpu,高併發對應的是訪問請求,能夠用單線程處理全部訪問請求,也能夠用多線程同時處理訪問請求。
在過去單CPU時代,單任務在一個時間點只能執行單一程序。以後發展到多任務階段,計算機能在同一時間點並行執行多任務或多進程。雖然並非真正意義上的「同一時間點」,而是多個任務或進程共享一個CPU,並交由操做系統來完成多任務間對CPU的運行切換,以使得每一個任務都有機會得到必定的時間片運行。
後來發展到多線程技術,使得在一個程序內部能擁有多個線程並行執行。一個線程的執行能夠被認爲是一個CPU在執行該程序。當一個程序運行在多線程下,就好像有多個CPU在同時執行該程序。
總之,多線程便可以這麼理解:多線程是處理高併發的一種編程方法,即併發須要用多線程實現。
高併發不是JAVA的專有的東西,是語言無關的廣義的,爲提供更好互聯網服務而提出的概念。典型的場景,例如:12306搶火車票,天貓雙十一秒殺活動等。該狀況的發生會致使系統在這段時間內執行大量操做,例如對資源的請求,數據庫的操做等。若是高併發處理很差,不只僅下降了用戶的體驗度(請求響應時間過長),同時可能致使系統宕機,嚴重的甚至致使OOM異常,系統中止工做等。
若是要想系統可以適應高併發狀態,則須要從各個方面進行系統優化,包括,硬件、網絡、系統架構、開發語言的選取、數據結構的運用、算法優化、數據庫優化等……而多線程只是其中解決方法之一。
Java多線程編程將會涉及到以下技術點:
一、併發編程三要素
原子性:即一個不可再被分割的顆粒。在Java中原子性指的是一個或多個操做要麼所有執行成功要麼所有執行失敗。
有序性:程序執行的順序按照代碼的前後順序執行。(處理器可能會對指令進行重排序)
可見性:當多個線程訪問同一個變量時,若是其中一個線程對其做了修改,其餘線程能當即獲取到最新的值。
二、 線程的五大狀態
建立狀態:當用 new 操做符建立一個線程的時候
就緒狀態:調用 start 方法,處於就緒狀態的線程並不必定立刻就會執行 run 方法,還須要等待CPU的調度
運行狀態:CPU 開始調度線程,並開始執行 run 方法
阻塞狀態:線程的執行過程當中因爲一些緣由進入阻塞狀態好比:調用 sleep 方法、嘗試去獲得一個鎖等等
死亡狀態:run 方法執行完 或者 執行過程當中遇到了一個異常
三、悲觀鎖與樂觀鎖
悲觀鎖:每次操做都會加鎖,會形成線程阻塞。
樂觀鎖:每次操做不加鎖而是假設沒有衝突而去完成某項操做,若是由於衝突失敗就重試,直到成功爲止,不會形成線程阻塞。
四、線程之間的協做
線程間的協做有:wait/notify/notifyAll等
五、synchronized 關鍵字
synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有如下幾種:
1)、修飾一個代碼塊:被修飾的代碼塊稱爲同步語句塊,其做用的範圍是大括號{}括起來的代碼,做用的對象是調用這個代碼塊的對象
2)、修飾一個方法:被修飾的方法稱爲同步方法,其做用的範圍是整個方法,做用的對象是調用這個方法的對象
3)、修改一個靜態的方法:其做用的範圍是整個靜態方法,做用的對象是這個類的全部對象
4)、修改一個類:其做用的範圍是synchronized後面括號括起來的部分,做用主的對象是這個類的全部對象。
六、CAS
CAS全稱是Compare And Swap,即比較替換,是實現併發應用到的一種技術。操做包含三個操做數—內存位置(V)、預期原值(A)和新值(B)。 若是內存位置的值與預期原值相匹配,那麼處理器會自動將該位置值更新爲新值 。不然,處理器不作任何操做。
CAS存在三大問題:ABA問題,循環時間長開銷大,以及只能保證一個共享變量的原子操做。
七、線程池
若是咱們使用線程的時候就去建立一個線程,雖然簡單,可是存在很大的問題。若是併發的線程數量不少,而且每一個線程都是執行一個時間很短的任務就結束了,這樣頻繁建立線程就會大大下降系統的效率,由於頻繁建立線程和銷燬線程須要時間。線程池經過複用能夠大大減小線程頻繁建立與銷燬帶來的性能上的損耗。
一、靜態資源結合CDN來解決圖片文件等訪問
二、分佈式緩存:redis、memcached等。
三、消息隊列中間件:activeMQ等,解決大量消息的異步處理能力。
四、應用拆分:一個工程被拆分爲多個工程部署,利用dubbo解決多工程之間的通訊。
五、數據庫垂直拆分和水平拆分(分庫分表)等。
六、數據庫讀寫分離,解決大數據的查詢問題。
七、利用nosql ,例如mongoDB配合mysql組合使用。
八、創建大數據訪問狀況下的服務降級以及限流機制等。
轉載:https://blog.csdn.net/liuhuiteng/article/details/88371292