版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、那么我們就需要考慮相關(guān)的并發(fā)訪問對于我們開發(fā)的網(wǎng)站, 如果網(wǎng)站的訪問量非常大的話, 問題了。 而并發(fā)問題是絕大部分的程序員頭疼的 問題,但話又說回來了,既然逃避不掉,那我們就坦然面對吧今天就讓我們一起來研究一下常見的并發(fā)和同步吧。為了更好的理解并發(fā)和同步,我們需要先明白兩個重要的概念:同步和異步1、同步和異步的區(qū)別和聯(lián)系所謂同步,可以理解為在執(zhí)行完一個函數(shù)或方法之后,一直等待系統(tǒng)返回值或消息,這時程序是出于阻塞的,只有接收到返回的值或消息后才往下執(zhí)行其它的命令。異步,執(zhí)行完函數(shù)或方法后,不必阻塞性地等待返回值或消息,只需要向系統(tǒng)委托一個異步過程,那么當系統(tǒng)接收到返回值或消息時,系統(tǒng)會自動觸發(fā)委
2、托的異步過程,從而完成一個完整的流程。同步在一定程度上可以看做是單線程,這個線程請求一個方法后就待這個方法給他回復(fù),否則他不往下執(zhí)行(死心眼)。異步在一定程度上可以看做是多線程的(廢話,一個線程怎么叫異步 ),請求一個方法后,就不管了,繼續(xù)執(zhí)行其他的方法。同步就是一件事,一件事情一件事的做。異步就是,做一件事情,不引響做其他事情。例如:吃飯和說話,只能一件事一件事的來,因為只有一張嘴。但吃飯和聽音樂是異步的,因為,聽音樂并不引響我們吃飯。對于Java程序員而言,我們會經(jīng)常聽到同步關(guān)鍵字synchronized,假如這個同步的監(jiān)視對象是類的話,那么如果當一個對象訪問類里面的同步方法的話,那么其它
3、的對象如果想要繼續(xù)訪問類里面的這個同步方法的話,就會進入阻塞,只有等前一個對象執(zhí)行完該同步方法后當前對象才能夠繼續(xù)執(zhí)行該方法。這就是同步。相反,如果方法前沒有同步關(guān)鍵字修飾的話,那么不同的對象可以在同一時間訪問同一個方法,這就是異步。在補充一下(臟數(shù)據(jù)和不可重復(fù)讀的相關(guān)概念 ):臟數(shù)據(jù)臟讀就是指當一個事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時,另外一個事務(wù)也訪問這個數(shù)據(jù),然后使用了這個數(shù)據(jù)。因為這個數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個事務(wù)讀到的這個數(shù)據(jù)是臟數(shù)據(jù)(Dirty Data),依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的。不可重復(fù)讀不可重復(fù)讀是指在一個事務(wù)內(nèi),多
4、次讀同一數(shù)據(jù)。在這個事務(wù)還沒有結(jié)束時,另外一個事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個事務(wù)的修改,那么第一個事務(wù)兩次讀到的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為是不可重復(fù)讀2、如何處理并發(fā)和同步今天講的如何處理并發(fā)和同同步問題主要是通過鎖機制。我們需要明白,鎖機制有兩個層面。一種是代碼層次上的,如java中的同步鎖,典型的就是同步關(guān)鍵字synchronized ,這里我不在做過多的講解,感興趣的可以參考:另外一種是數(shù)據(jù)庫層次上的,比較典型的就是悲觀鎖和樂觀鎖。這里我們重點講解的就 是悲觀鎖(傳統(tǒng)的物理鎖)和樂觀鎖。悲觀鎖(P
5、essimistic Locking):悲觀鎖,正如其名,它指的是對數(shù)據(jù)被外界(包括本系統(tǒng)當前的其他事務(wù),以及來自外 部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實現(xiàn),往往依靠數(shù)據(jù)庫提供的鎖機制(也只有數(shù)據(jù)庫層提供的鎖機制才能真正 保證數(shù)據(jù)訪問的排他性,否則,即使在本系統(tǒng)中實現(xiàn)了加鎖機制,也無法保證外部系統(tǒng)不會修改數(shù)據(jù))。一個典型的倚賴數(shù)據(jù)庫的悲觀鎖調(diào)用:select * from account where name=" Erica " for update這條sql語句鎖定了 account表中所有符合檢索條件(name=&
6、quot; Erica。的記錄。本次事務(wù)提交之前(事務(wù)提交時會釋放事務(wù)過程中的鎖),外界無法修改這些記錄。?Hibernate的悲觀鎖,也是基于數(shù)據(jù)庫的鎖機制實現(xiàn)。?下面的代碼實現(xiàn)了對查詢記錄的加鎖:String hqlStr ="from TUser as user where ='Erica'"Query query = (hqlStr);("user",; UPGRADE_NOWAIT : Oracle 的特定實現(xiàn),利用 Oracle 的 forupdate nowait 子句實現(xiàn)加鎖。?上面這兩種鎖機制是我們在應(yīng)用層較為常用的,加
7、鎖一般通過以下方法實現(xiàn):?注意,只有在查詢開始之前(也就是Hiberate生成SQL之前)設(shè)定加鎖,才會?真正通過數(shù)據(jù)庫的鎖機制進行加鎖處理,否則,數(shù)據(jù)已經(jīng)通過不包含for update子句的Select SQL加載進來,所謂數(shù)據(jù)庫加鎖也就無從談起。為了更好的理解 select. for update 的鎖表的過程,本人將要以mysql為例,進行相應(yīng)的講解1、要測試鎖定的狀況,可以利用 MySQL的Command Mode ,開二個視窗來做測試。表的基本結(jié)構(gòu)如下:表中內(nèi)容如下:開啟兩個測試窗口,在其中一個窗口執(zhí)行select * from ta for update。然后在另外一個窗口執(zhí)行up
8、date操作如下圖:等到一個窗口 commit后的圖片如下:到這里,悲觀鎖機制你應(yīng)該了解一些了吧需要注意的是for update要放到mysql的事務(wù)中,即begin和commit中,否者不起 作用。至于是鎖住整個表還是鎖住選中的行,請參考:至于hibernate中的悲觀鎖使用起來比較簡單,這里就不寫demo 了感興趣的自己查一下就 ok 了樂觀鎖(Optimistic Locking):?相對悲觀鎖而言,樂觀鎖機制采取了更加寬松的加鎖機制。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫的鎖機制實現(xiàn),以保證操作最大程度的獨占性。但隨之而來的就是數(shù)據(jù)庫性能的大量開銷,特別是對長事務(wù)而言,這樣的開銷往往無法承受。如
9、一個金融系統(tǒng),當某個操作員讀取用戶的數(shù)據(jù),并在讀出的用戶數(shù)據(jù)的基礎(chǔ)上進行修改時(如更改用戶帳戶余額),如果采用悲觀鎖機制,也就意味著整個操作過程中(從操作員讀出數(shù)據(jù)、開始修改直至提交修改結(jié)果的全過程,甚至還包括操作員中途去煮咖啡的時間),數(shù)據(jù)庫記錄始終處于加鎖狀態(tài),可以想見,如果面對幾百上千個并發(fā),這樣的情況將導(dǎo)致怎樣的后果。樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基于數(shù)據(jù)版本 Version )記錄機制實現(xiàn)。何謂數(shù)據(jù)版本即為數(shù)據(jù)增加一個 版本標識,在基于數(shù)據(jù)庫表的版本解決方案中,一般是通過為數(shù)據(jù)庫表增加一個“version '字段來實現(xiàn)。讀取出數(shù)據(jù)時,將此版本號一同讀出,
10、之后更新時,對此版本號加一。此時,將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫表對應(yīng)記錄的當前版本信息進行比對,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當前版本號, 則予以更新,否則認為是過期數(shù)據(jù)。對于上面修改用戶帳戶信息的例子而言,假設(shè)數(shù)據(jù)庫中帳戶信息表中有一個version字段,當前值為 1 ;而當前帳戶余額字段(balance )為$100 。操作員 A此時將其讀出(version=1 ),并從其帳戶余額中扣除$50 ( $100-$50 )。2在操彳員 A操作的過程中,操作員 B也讀入此用戶信息(version=1 ),并從其帳戶余額中扣除 $20 ( $100-$20 ) 。 3操作員A完成了修改工作,將數(shù)
11、據(jù)版本號加一(version=2 ),連同帳戶扣除后余額( balance=$50 ),提交至數(shù)據(jù)庫更新,此時由于提交數(shù)據(jù)版本大于數(shù)據(jù)庫記錄當前版本,數(shù)據(jù)被更新,數(shù)據(jù)庫記錄version更新為2 。4操作員B完成了操作,也將版本號加一(version=2 )試圖向數(shù)據(jù)庫提交數(shù)據(jù)( balance=$80 ),但此時比對數(shù)據(jù)庫記錄版本時發(fā)現(xiàn),操作員 B提交的數(shù)據(jù)版本號為 2 ,數(shù)據(jù)庫記錄當前版本也為2 ,不滿足“提交版本必須大于記錄當前版本才能執(zhí)行更新"的樂觀鎖策略,因此,操作員 B的提交被駁回。這樣,就避免了操作員B用基于version=1的舊數(shù)據(jù)修改的結(jié)果覆蓋操作員A的操作結(jié)果的可
12、能。從上面的例子可以看出,樂觀鎖機制避免了長事務(wù)中的數(shù)據(jù)庫加鎖開銷(操作員A和操作員B操作過程中,都沒有對數(shù)據(jù)庫數(shù)據(jù)加鎖),大大提升了大并發(fā)量下的系統(tǒng)整體 性能表現(xiàn)。需要注意的是,樂觀鎖機制往往基于系統(tǒng)中的數(shù)據(jù)存儲邏輯,因此也具備一定的局限性,如在上例中,由于樂觀鎖機制是在我們的系統(tǒng)中實現(xiàn),來 自外部系統(tǒng)的用戶余額更新操作不受我們系統(tǒng)的控制,因此可能會造成臟數(shù)據(jù)被更新到數(shù)據(jù)庫中。在系統(tǒng)設(shè)計階段,我們應(yīng)該充分考慮到這些情況出現(xiàn)的可能性,并進行相應(yīng)調(diào)整(如將樂觀鎖策略在數(shù)據(jù)庫存儲過程中實現(xiàn),對外只開放基于此存儲過程的數(shù)據(jù)更新途徑,而不是將數(shù)據(jù)庫表直接對外公開)。Hibernate在其數(shù)據(jù)訪問引擎中
13、內(nèi)置了樂觀鎖實現(xiàn)。如果不用考慮外部系統(tǒng)對數(shù)據(jù)庫的更新操作,利用Hibernate提供的透明化樂觀鎖實現(xiàn),將大大提升我們的生產(chǎn)力。<xml version=""> <! DOCTYPE hibernate-mapping PUBLIC"- onfigure();SessionFactory sf=();Session session=();Transaction tx=();xecuteUpdate();User user=(User) , 1);("221");onfigure();SessionFactory sf=();S
14、ession session=(); niqueResult();niqueResult();Transaction tx=(); ("101");(); onfigure();SessionFactory sf=();Session session=();niqueResult();(10000);niqueResult();Transaction tx=(); ("100");();能web線程連接數(shù)不夠3.可能數(shù)據(jù)庫連接查詢上不去。根據(jù)不同的情況,解決思路也不同。1 .像第一種情況可以增加網(wǎng)絡(luò)帶寬, DNS域名解析分發(fā)多臺服務(wù)器。2 .負載均衡,前
15、置代理服務(wù)器nginx、apache等等3 .數(shù)據(jù)庫查詢優(yōu)化,讀寫分離,分表等等最后復(fù)制一些在高并發(fā)下面需要常常需要處理的內(nèi)容:?盡量使用緩存,包括用戶緩存,信息緩存等,多花點內(nèi)存來做緩存,可以大量減少 與數(shù)據(jù)庫的交互,提高性能。?用jprofiler等工具找出性能瓶頸,減少額外的開銷。?優(yōu)化數(shù)據(jù)庫查詢語句,減少直接使用hibernate等工具的直接生成語句(僅耗時較長的查詢做優(yōu)化)。?優(yōu)化數(shù)據(jù)庫結(jié)構(gòu),多做索引,提高查詢效率。?統(tǒng)計的功能盡量做緩存,或按每天一統(tǒng)計或定時統(tǒng)計相關(guān)報表,避免需要時進行統(tǒng) 計的功能。?能使用靜態(tài)頁面的地方盡量使用,減少容器的解析(盡量將動態(tài)內(nèi)容生成靜態(tài)html來顯示
16、)。?解決以上問題后,使用服務(wù)器集群來解決單臺的瓶頸問題。java高并發(fā),如何解決,什么方式解決之前我將高并發(fā)的解決方法誤認為是線程或者是隊列可以解決,因為高并發(fā)的時候是有很多用戶在訪問,導(dǎo)致出現(xiàn)系統(tǒng)數(shù)據(jù)不正確、丟失數(shù)據(jù)現(xiàn)象,所以想到的是用隊列解決,其實隊列解決的方式也可以處理,比如我們在競拍商品、轉(zhuǎn)發(fā)評論微博或者是秒殺商品等,同一時間訪問量特別大,隊列在此起到特別的作用,將所有請求放入隊列,以毫秒計時單位,有序的進行,從 而不會出現(xiàn)數(shù)據(jù)丟失系統(tǒng)數(shù)據(jù)不正確的情況。今天我經(jīng)過查資料,高并發(fā)的解決方法有倆種:一種是使用緩存、另一種是使用生成靜態(tài)頁面;還有就是從最基礎(chǔ)的地方優(yōu)化我們寫代碼減 少不必要
17、的資源浪費:(1 .不要頻繁的new對象,對于在整個應(yīng)用中只需要存在一個實例的類使用單例模式.對于String的連接操作,使用StringBuffer或者StringBuilder.對于utility類型的類通過靜態(tài)方法來 訪問。2 .避免使用錯誤的方式,如Exception可以控制方法推出,但是Exception要保留stacktrace 消耗性能,除非必要不要使用instanceof做條件判斷,盡量使用比的條件判斷方式.使用JAVA中效率高的類,比如ArrayList比Vector性能好。)首先緩存技術(shù)我一直沒有使用過,我覺得應(yīng)該是在用戶請求時將數(shù)據(jù)保存在緩存中,下次請求時會檢測緩存中是否
18、有數(shù)據(jù)存在, 防止多次請求服務(wù)器, 導(dǎo)致服務(wù)器性能降低, 嚴重導(dǎo)致 服務(wù)器崩潰,這只是我自己的理解,詳細的資料還是需要在網(wǎng)上收集;使用生成靜態(tài)頁面我想大家應(yīng)該不模式,我們見過很多網(wǎng)站當在請求的時候頁面的后最已經(jīng)變了,如”該頁面其實是一個服務(wù)器請求地址,在轉(zhuǎn)換成htm后,訪問速度將提升,因為靜態(tài)頁面不帶有服務(wù)器組件;在這里我就多多介紹一下:一、什么是頁面靜態(tài)化:簡 單的說,我們?nèi)绻L問一個鏈接 ,服務(wù)器對應(yīng)的模塊會處理這個請求,轉(zhuǎn)到對應(yīng)的 jsp 界面,最后生成我們想要看到的數(shù)據(jù)。 這其中的缺點是顯而易見的: 因為每次請求服務(wù)器都 會進行處理,如 果有太多的高并發(fā)請求,那么就會加重應(yīng)用服務(wù)器的壓
19、力,弄不好就把服務(wù)器搞down掉了。那么如何去避免呢如果我們把對請求后的結(jié)果彳存成一個html文件,然后每次用戶都去訪問,這樣應(yīng)用服務(wù)器的壓力不就減少了那么靜態(tài)頁面從哪里來呢總不能讓我們每個頁面都手動處理吧這里就牽涉到我們要講解的內(nèi)容了,靜態(tài)頁面生成方案 我們需要的是自動的生成靜態(tài)頁面,當用戶訪問,會自動生成,然后顯示給用戶。二、下面我們在簡單介紹一下要想掌握頁面靜態(tài)化方案應(yīng)該掌握的知識點:1、 基礎(chǔ)-URL Rewrite什么是URL Rewrite 呢 URL重寫。用一個簡單的例子來說明問題:輸入網(wǎng)址,但是實際上訪問的卻是,那我們就可以說 URL被重寫了。這項技術(shù)應(yīng)用廣泛,有許多開源的工具
20、可 以實現(xiàn)這個功能。2、 基礎(chǔ)-Servlet如果你還不知道中一個請求和一個servlet是如何匹配到一起的,那么請搜索一下servlet的文檔。這可不是亂說呀,有很多人就認為/xyz/*.do這樣的匹配方式能有效。如果你還不知道怎么編寫一個servlet ,那么請搜索一下如何編寫servlet.這可不是說笑呀,在各種集成工具漫天飛舞的今天,很多人都不會去從零編寫一個servlet 了。三、基本的方案介紹其中,對于 URL Rewriter的部分,可以使用收費或者開源的工具來實現(xiàn),如果url不是特別的復(fù)雜,可以考慮在servlet中實現(xiàn),那么就是下面這個樣子:總 結(jié):其實我們在開發(fā)中都很少考慮這種問題,直接都是先將功能實現(xiàn),當一個程序員在干到1到2年,就會感覺光實現(xiàn)功能不是最主要的,安全性能、質(zhì)量等等才是一個開發(fā)人員最該關(guān)心的。今天我所說的是高并發(fā)。我的解決思路是:1、采用分布式應(yīng)用設(shè)計2、分布式緩存數(shù)據(jù)庫3、代碼優(yōu)化Java高并發(fā)的例
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度新型城鎮(zhèn)化建設(shè)渣土處理承包協(xié)議3篇
- 二零二五年度高空監(jiān)測設(shè)備搭設(shè)鋼管腳手架安裝合同3篇
- 2025版高端美甲店經(jīng)營管理權(quán)轉(zhuǎn)讓合同樣本4篇
- 2025年度個人汽車租賃售后服務(wù)合同范本7篇
- 二零二五年度模具設(shè)計與制造一體化服務(wù)合同2篇
- 2025年度餐飲廚房承包項目合同范本(含廚師團隊)4篇
- 二零二五年度特色美食街廚師技能承包合作協(xié)議3篇
- 個人電子煙零售店加盟合同(2024年度)3篇
- 二零二五年度城市綠化用地承包合同范本4篇
- 2025年度個人房產(chǎn)抵押借款合同修訂版8篇
- 2024年全國甲卷高考化學試卷(真題+答案)
- 汽車修理廠管理方案
- 人教版小學數(shù)學一年級上冊小學生口算天天練
- 三年級數(shù)學添括號去括號加減簡便計算練習400道及答案
- 蘇教版五年級上冊數(shù)學簡便計算300題及答案
- 澳洲牛肉行業(yè)分析
- 老客戶的開發(fā)與技巧課件
- 計算機江蘇對口單招文化綜合理論試卷
- 成人學士學位英語單詞(史上全面)
- KAPPA-實施方法課件
- GB/T 13813-2023煤礦用金屬材料摩擦火花安全性試驗方法和判定規(guī)則
評論
0/150
提交評論