亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

淺析Java 并發(fā)編程中的synchronized

瀏覽:2日期:2022-08-20 09:14:41

synchronized關(guān)鍵字,我們一般稱之為“同步鎖”,用它來(lái)修飾需要同步的方法和需要同步代碼塊,默認(rèn)是當(dāng)前對(duì)象作為鎖的對(duì)象。在用synchronized修飾類時(shí)(或者修飾靜態(tài)方法),默認(rèn)是當(dāng)前類的Class對(duì)象作為鎖的對(duì)象,故存在著方法鎖、對(duì)象鎖、類鎖這樣的概念。

一、沒(méi)有設(shè)置線程同步的情況

先給出以下代碼感受下代碼執(zhí)行的時(shí)候?yàn)槭裁葱枰剑看a可能比較枯燥,配上業(yè)務(wù)理解起來(lái)就會(huì)舒服很多,學(xué)生軍訓(xùn),有三列,每列5人,需要報(bào)數(shù),每個(gè)線程負(fù)責(zé)每一列報(bào)數(shù)。

class SynchronizedExample {protected static int num = 0;protected void numberOff() {for(int i=0; i<5; i++) {num++;System.out.println(Thread.currentThread().getName()+':'+SynchronizedExample.num);}}}public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {SynchronizedExample se = new SynchronizedExample();for(int i=1; i<=3; i++) {new Thread( ()-> {se.numberOff();}, '線程'+i).start();}}}

執(zhí)行結(jié)果如下:

線程1:1線程2:2線程1:3線程3:4.......

之所以出現(xiàn)這種情況,是因?yàn)槿齻€(gè)線程是異步的,沒(méi)有同步。對(duì)應(yīng)的業(yè)務(wù)場(chǎng)景就是,在第一列沒(méi)有完成報(bào)數(shù)的時(shí)候,其他隊(duì)列搶報(bào)了,這在現(xiàn)實(shí)中是不允許的,所以需要類似于synchronized等具有同步功能的關(guān)鍵字粉末登場(chǎng)。

二、方法同步鎖

當(dāng)報(bào)數(shù)方法加上synchronized關(guān)鍵字之后,就會(huì)一列一列的報(bào)數(shù)。

protected synchronized void numberOff() {for(int i=0; i<5; i++) {num++;System.out.println(Thread.currentThread().getName()+':'+SynchronizedExample.num);}}

執(zhí)行結(jié)果如下:

線程1:1線程1:2線程1:3線程1:4......

寫(xiě)到這里還是要從技術(shù)層面講下原理,當(dāng)一個(gè)線程執(zhí)行帶有synchronized關(guān)鍵字的方法時(shí),該線程會(huì)在該方法處設(shè)置一個(gè)鎖(其他線程打不開(kāi)這個(gè)鎖,只能在外邊等該線程釋放掉該鎖,一般都是執(zhí)行完所有代碼后主動(dòng)釋放鎖),表示此方法是當(dāng)前線程獨(dú)占的,對(duì)應(yīng)到上述業(yè)務(wù)中就是一次只能有一個(gè)隊(duì)列報(bào)數(shù)。

三、對(duì)象鎖

改進(jìn)后的代碼用到了一個(gè)對(duì)象鎖,該對(duì)象鎖默認(rèn)是當(dāng)前對(duì)象,上述代碼等同于以下代碼:

protected void numberOff() {synchronized (this) {for (int i = 0; i < 5; i++) {num++;System.out.println(Thread.currentThread().getName() + ':' + SynchronizedExample.num);}}}

當(dāng)多個(gè)線程用一個(gè)對(duì)象鎖,各個(gè)線程可以達(dá)到同步的作用,如果每個(gè)線程都用自己的對(duì)象鎖,那么synchronized就失去了同步的作用。如以下代碼:

class SynchronizedExample {protected static int num = 0;protected void numberOff() {synchronized (this) {for (int i = 0; i < 5; i++) {num++;System.out.println(Thread.currentThread().getName() + ':' + SynchronizedExample.num);}}}}public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {SynchronizedExample se = new SynchronizedExample();for(int i=1; i<=3; i++) {new Thread( ()-> {new SynchronizedExample().numberOff();}, '隊(duì)列'+i).start();}}}

執(zhí)行結(jié)果如下:

線程1:1線程2:2線程1:3線程3:4.......

有讀者會(huì)說(shuō)不同線程執(zhí)行的是不同對(duì)象中的方法,肯定達(dá)不到同步的效果,也對(duì),也很有道理,接著看如下代碼:

class SynchronizedExample {protected static int num = 0;protected void numberOff(Object lock) {synchronized (lock) {for (int i = 0; i < 5; i++) {num++;System.out.println(Thread.currentThread().getName() + ':' + SynchronizedExample.num);}}}}public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {SynchronizedExample se = new SynchronizedExample();for(int i=1; i<=3; i++) {new Thread( ()-> {se.numberOff(new Object());}, '隊(duì)列'+i).start();}}}

執(zhí)行結(jié)果如下:

線程1:1線程2:2線程1:3線程3:4.......

四、類鎖

對(duì)于上述問(wèn)題,讀者應(yīng)該得出一個(gè)結(jié)論,要想達(dá)到同步的效果,必須用同一個(gè)鎖,此時(shí)類鎖可以粉末登場(chǎng)。看如下代碼:

protected void numberOff(Object lock) {synchronized (SynchronizedExample.class) {for (int i = 0; i < 5; i++) {num++;System.out.println(Thread.currentThread().getName() + ':' + SynchronizedExample.num);}}}

上述代碼可以達(dá)到同步的效果。

五、靜態(tài)鎖

靜態(tài)鎖是針對(duì)靜態(tài)方法而言,當(dāng)一個(gè)靜態(tài)方法中有synchronized關(guān)鍵字時(shí),默認(rèn)的是使用當(dāng)前類字節(jié)碼對(duì)象作為鎖。代碼示例如下:

class SynchronizedExample {protected static int num = 0;protected synchronized static void numberOff() {for (int i = 0; i < 5; i++) {num++;System.out.println(Thread.currentThread().getName() + ':' + SynchronizedExample.num);}}}public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {for (int i = 1; i <= 3; i++) {new Thread(() -> { new SynchronizedExample().numberOff(); }, '隊(duì)列' + i).start();}}}

六、線程池實(shí)現(xiàn)

最后用線程池將上述代碼寫(xiě)一下

package ioo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;class SynchronizedExample {protected static int num = 0;protected synchronized static void numberOff() {for (int i = 0; i < 5; i++) {num++;System.out.println(Thread.currentThread().getName() + ':' + SynchronizedExample.num);}}}public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newCachedThreadPool();for(int i=1; i<=3; i++) {executorService.execute(() -> new SynchronizedExample().numberOff());}}}

以上就是淺析Java 并發(fā)編程中的synchronized的詳細(xì)內(nèi)容,更多關(guān)于Java 并發(fā)編程 synchronized的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 久久成人在线观看 | 三级黄色在线免费观看 | 特黄一级真人毛片 | 一本久道久久综合 | 日韩欧美一二三区 | 亚洲精品三级 | 色在线播放 | 免费看a级片 | 超级碰碰碰碰97久久久久 | 在线播放亚洲美女视频网站 | 97超级碰久久久久香蕉人人 | 久久精品国产亚洲网站 | 干综合网| 91免费国产在线观看 | 久久精品国产91久久麻豆自制 | 一级黄色片在线观看 | 91在线精品免费观看 | 国产第一页无线好源 | 的九一视频入口在线观看 | 特色一级黄色片 | 日韩欧美第一区二区三区 | 欧美日韩综合在线视频免费看 | 久久99国产亚洲精品观看 | 91porn在线观看国产 | 国产精品免费入口视频 | 香蕉成人啪国产精品视频综合网 | 免费直接看黄 | 色婷婷久| 露脸真实国产精品自在| 成人啪啪免费视频 | 国产精品久久免费观看 | 一级大毛片 | 青青青在线视频国产 | 六月丁香婷婷综合 | 黄色免费在线观看网址 | 在线观看免费视频网站色 | 亚洲人和日本人hd | 亚洲精品自产拍在线观看 | 国产在线观看91精品不卡 | 女黄色片| 国产一区二区三区在线免费 |