并发编程之Synchronized
在介紹Synchrinized之前,我們先來(lái)了解一下并發(fā)的相關(guān)概念。
什么是并發(fā)?
并發(fā): 同一時(shí)間段,多個(gè)任務(wù)都在執(zhí)行 (單位時(shí)間內(nèi)不一定同時(shí)執(zhí)行);在同一時(shí)刻只會(huì)有一條指令執(zhí)行,但是多個(gè)指令被快速輪換執(zhí)行,這個(gè)切換的時(shí)間非常短以至于我們不用去考慮它,這就是并發(fā)的基本含義。
而多線程正是我們可以完成并發(fā)的很重要的執(zhí)行手段。現(xiàn)在的系統(tǒng)動(dòng)不動(dòng)就要求百萬(wàn)級(jí)的并發(fā)量,而多線程并發(fā)編程正是開(kāi)發(fā)高并發(fā)系統(tǒng)的基礎(chǔ),利用好多線程的特性可以大大的提高我們的系統(tǒng)運(yùn)行的效率。而且當(dāng)今正值多核CPU時(shí)代,多線程也可以提高我們CPU的利用效率,最大化的利用我們現(xiàn)有的資源。
上文說(shuō)了多線程這么多的好處,那么它有什么缺點(diǎn)呢?
我們?cè)诙嗑€程的環(huán)境下,系統(tǒng)的執(zhí)行順序并不是由我們控制的,執(zhí)行的線程就可能隨時(shí)切換到其他線程中執(zhí)行。這就可能會(huì)造成一些安全性的問(wèn)題。 比如小A小B兩個(gè)人同時(shí)在搶票(僅剩一張),小A買(mǎi)票的線程先執(zhí)行,判斷?num?是否大于0(現(xiàn)在?num?=1),然后?num--。執(zhí)行完這個(gè)操作之后,小B線程也開(kāi)始執(zhí)行,也開(kāi)始判斷?num?是否大于0,因?yàn)樾更新的num尚未更新到主存中,小B的工作空間的?num?值還是大于1,所以也執(zhí)行?num--。
這個(gè)時(shí)候問(wèn)題就出現(xiàn)了,只有一張票,做了兩次?num--,最后num的值為-1系統(tǒng)就出現(xiàn)了錯(cuò)誤。那么如何防止這種現(xiàn)象出現(xiàn)呢?這里我們就引入了?Synchronzied。
什么是Synchronzied?
Synchronized?關(guān)鍵字解決的是多個(gè)線程之間訪問(wèn)資源的同步性,Synchronized?關(guān)鍵字可以保證被它修飾的方法或者代碼塊在任意時(shí)刻只能有一個(gè)線程執(zhí)行。
還用剛才的買(mǎi)票問(wèn)題舉例,下面是代碼
while (true) {synchronized (obj) {if (ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":" + ticket--);}}}復(fù)制代碼這次我們使用了?Synchronized?來(lái)對(duì)整個(gè)?if?語(yǔ)句進(jìn)行修飾,就保證了if語(yǔ)句的原子性,只有當(dāng)整個(gè)?if?語(yǔ)句的代碼執(zhí)行完畢的時(shí)候,才會(huì)釋放鎖,我們也就很容易的解決了買(mǎi)票的問(wèn)題。
下面我們來(lái)介紹一下?Synchronzied?的主要使用方式
synchronized?關(guān)鍵字最主要的三種使用方式:
* 修飾實(shí)例方法: 作用于當(dāng)前對(duì)象實(shí)例加鎖,進(jìn)入同步代碼前要獲得當(dāng)前對(duì)象實(shí)例的鎖
* 修飾靜態(tài)方法: 也就是給當(dāng)前類加鎖,會(huì)作用于類的所有對(duì)象實(shí)例,因?yàn)殪o態(tài)成員不屬于任何一個(gè)實(shí)例對(duì)象,是類成員( static表明這是該類的一個(gè)靜態(tài)資源,不管new了多少個(gè)對(duì)象,只有一份)。所以如果一個(gè)線程A調(diào)用一個(gè)實(shí)例對(duì)象的非靜態(tài) synchronized 方法,而線程B需要調(diào)用這個(gè)實(shí)例對(duì)象所屬類的靜態(tài) synchronized 方法,是允許的,不會(huì)發(fā)生互斥現(xiàn)象,因?yàn)樵L問(wèn)靜態(tài) synchronized 方法占用的鎖是當(dāng)前類的鎖,而訪問(wèn)非靜態(tài) synchronized 方法占用的鎖是當(dāng)前實(shí)例對(duì)象鎖。
* 修飾代碼塊: 指定加鎖對(duì)象,對(duì)給定對(duì)象加鎖,進(jìn)入同步代碼庫(kù)前要獲得給定對(duì)象的鎖。
這些就是今天介紹?Synchronized?的全部?jī)?nèi)容,今后我也會(huì)持續(xù)在我的專欄中更新更多有價(jià)值的內(nèi)容,歡迎關(guān)注。
轉(zhuǎn)載于:https://juejin.im/post/5ced2ccf6fb9a07ed2244ecf
超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的并发编程之Synchronized的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 基础关1
- 下一篇: celery开发中踩的坑