日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

詳解Java并發(fā)編程之內(nèi)置鎖(synchronized)

瀏覽:26日期:2022-08-15 16:17:13
簡介

synchronized在JDK5.0的早期版本中是重量級鎖,效率很低,但從JDK6.0開始,JDK在關(guān)鍵字synchronized上做了大量的優(yōu)化,如偏向鎖、輕量級鎖等,使它的效率有了很大的提升。

synchronized的作用是實現(xiàn)線程間的同步,當(dāng)多個線程都需要訪問共享代碼區(qū)域時,對共享代碼區(qū)域進(jìn)行加鎖,使得每一次只能有一個線程訪問共享代碼區(qū)域,從而保證線程間的安全性。

因為沒有顯式的加鎖和解鎖過程,所以稱之為隱式鎖,也叫作內(nèi)置鎖、監(jiān)視器鎖。

如下實例,在沒有使用synchronized的情況下,多個線程訪問共享代碼區(qū)域時,可能會出現(xiàn)與預(yù)想中不同的結(jié)果。

public class Apple implements Runnable { private int appleCount = 5; @Override public void run() { eatApple(); } public void eatApple(){ appleCount--; System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果'); } public static void main(String[] args) { Apple apple = new Apple(); Thread t1 = new Thread(apple, '小強(qiáng)'); Thread t2 = new Thread(apple, '小明'); Thread t3 = new Thread(apple, '小花'); Thread t4 = new Thread(apple, '小紅'); Thread t5 = new Thread(apple, '小黑'); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); }}

可能會輸出如下結(jié)果:

小強(qiáng)吃了一個蘋果,還剩3個蘋果小黑吃了一個蘋果,還剩3個蘋果小明吃了一個蘋果,還剩2個蘋果小花吃了一個蘋果,還剩1個蘋果小紅吃了一個蘋果,還剩0個蘋果

輸出結(jié)果異常的原因是eatApple方法里操作不是原子的,如當(dāng)A線程完成appleCount的賦值,還沒有輸出,B線程獲取到appleCount的最新值,并完成賦值操作,然后A和B同時輸出。(A,B線程分別對應(yīng)小黑、小強(qiáng))

如果改下eatApple方法如下,還會不會有線程安全問題呢?

public void eatApple(){System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + --appleCount + '個蘋果');}

還是會有的,因為--appleCount不是原子操作,--appleCount可以用另外一種寫法表示:appleCount = appleCount - 1,還是有可能會出現(xiàn)以上的異常輸出結(jié)果。

synchronized的使用

synchronized分為同步方法和同步代碼塊兩種用法,當(dāng)每個線程訪問同步方法或同步代碼塊區(qū)域時,首先需要獲得對象的鎖,搶到鎖的線程可以繼續(xù)執(zhí)行,搶不到鎖的線程則阻塞,等待搶到鎖的線程執(zhí)行完成后釋放鎖。

1.同步代碼塊

鎖的對象是object:

public class Apple implements Runnable { private int appleCount = 5; private Object object = new Object(); @Override public void run() { eatApple(); } public void eatApple(){//同步代碼塊,此時鎖的對象是object synchronized (object) { appleCount--; System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果'); } } //...省略main方法}

2.同步方法,修飾普通方法

鎖的對象是當(dāng)前類的實例對象:

public class Apple implements Runnable { private int appleCount = 5; @Override public void run() { eatApple(); } public synchronized void eatApple() { appleCount--; System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果'); } //...省略main方法}

等價于以下同步代碼塊的寫法:

public void eatApple() {synchronized (this) {appleCount--;System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果');}}

3.同步方法,修飾靜態(tài)方法

鎖的對象是當(dāng)前類的class對象:

public class Apple implements Runnable { private static int appleCount = 5; @Override public void run() { eatApple(); } public synchronized static void eatApple() { appleCount--; System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果'); } //...省略main方法}

等價于以下同步代碼塊的寫法:

public static void eatApple() {synchronized (Apple.class) {appleCount--;System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果');}}

4.同步方法和同步代碼塊的區(qū)別

a.同步方法鎖的對象是當(dāng)前類的實例對象或者當(dāng)前類的class對象,而同步代碼塊鎖的對象可以是任意對象。

b.同步方法是使用synchronized修飾方法,而同步代碼塊是使用synchronized修飾共享代碼區(qū)域。同步代碼塊相對于同步方法來說粒度更細(xì),鎖的區(qū)域更小,一般鎖范圍越小效率就越高。如下情況顯然同步代碼塊更適用:

public static void eatApple() {//不需要同步的耗時操作1//...synchronized (Apple.class) {appleCount--;System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果');}//不需要同步的耗時操作2//...}

內(nèi)置鎖的可重入性

內(nèi)置鎖的可重入性是指當(dāng)某個線程試圖獲取一個它已經(jīng)持有的鎖時,它總是可以獲取成功。如下:

public static void eatApple() {synchronized (Apple.class) {synchronized (Apple.class) {synchronized (Apple.class) {appleCount--;System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果');}}}}

如果鎖不是可重入的,那么假如某線程持有了該鎖,然后又需要等待持有該鎖的線程釋放鎖,這不就造成死鎖了嗎?

synchronized可以被繼承嗎?

synchronized不可以被繼承,如果子類中重寫后的方法需要實現(xiàn)同步,則需要手動添加synchronized關(guān)鍵字。

public class AppleParent { public synchronized void eatApple(){ }}public class Apple extends AppleParent implements Runnable { private int appleCount = 5; @Override public void run() { eatApple(); } @Override public void eatApple() { appleCount--; System.out.println(Thread.currentThread().getName() + '吃了一個蘋果,還剩' + appleCount + '個蘋果'); } //...省略main方法}基于內(nèi)置鎖的等待和喚醒

基于內(nèi)置鎖的等待和喚醒是使用Object類中的wait()和notify()或notifyAll()來實現(xiàn)的。這些方法的調(diào)用前提是已經(jīng)持有對應(yīng)的鎖,所以只能在同步方法或者同步代碼塊里調(diào)用。如果在沒有獲取到對應(yīng)鎖的情況下調(diào)用則會拋出IllegalMonitorStateException異常。下面介紹下相關(guān)的幾個方法:

wait():使當(dāng)前線程無限期地等待,直到另一個線程調(diào)用notify()或notifyAll()。

wait(long timeout):指定一個超時時間,超時時間過后線程將會被自動喚醒。線程也可以在超時時間之前被notify()或notifyAll()喚醒。注意,wait(0)等同于調(diào)用wait()。

wait(long timeout, int nanos):類似于wait(long timeout),主要區(qū)別是wait(long timeout, int nanos)提供了更高的精度。

notify():隨機(jī)喚醒一個在相同鎖對象上等待的線程。

notifyAll():喚醒所有在相同鎖對象上等待的線程。

一個簡單的等待喚醒實例:

public class Apple { //蘋果數(shù)量 private int appleCount = 0; /** * 買蘋果 */ public synchronized void getApple() { try { while (appleCount != 0) { wait(); } } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println(Thread.currentThread().getName() + '買了5個蘋果'); appleCount = 5; notify(); } /** * 吃蘋果 */ public synchronized void eatApple() { try { while (appleCount == 0) { wait(); } } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println(Thread.currentThread().getName() + '吃了1個蘋果'); appleCount--; notify(); }}

/** * 生產(chǎn)者,買蘋果 */public class Producer extends Thread{ private Apple apple; public Producer(Apple apple, String name){ super(name); this.apple = apple; } @Override public void run(){ while (true) apple.getApple(); }}/** * 消費(fèi)者,吃蘋果 */public class Consumer extends Thread{ private Apple apple; public Consumer(Apple apple, String name){ super(name); this.apple = apple; } @Override public void run(){ while (true) apple.eatApple(); }}

public class Demo { public static void main(String[] args) { Apple apple = new Apple(); Producer producer = new Producer(apple,'小明'); Consumer consumer = new Consumer(apple, '小紅'); producer.start(); consumer.start(); }}

輸出結(jié)果:

小明買了5個蘋果小紅吃了1個蘋果小紅吃了1個蘋果小紅吃了1個蘋果小紅吃了1個蘋果小紅吃了1個蘋果小明買了5個蘋果小紅吃了1個蘋果 ......

到此這篇關(guān)于Java并發(fā)編程之內(nèi)置鎖(synchronized)的文章就介紹到這了,更多相關(guān)Java內(nèi)置鎖內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲免费观看高清完整版在线观| 日韩另类视频| 精品美女视频| 国产精品tv| 国产乱码精品一区二区三区亚洲人 | 欧美午夜精彩| 国产精品亚洲一区二区在线观看| 999国产精品永久免费视频app| 中文字幕中文字幕精品| 91精品在线观看国产| 国产福利片在线观看| 欧美激情福利| 国产欧美日韩在线一区二区| 丝袜美腿成人在线| 三级亚洲高清视频| 午夜精品婷婷| 性欧美videohd高精| 久久天堂av| 亚洲成人精品| 亚洲精品一区三区三区在线观看| 国产一区二区亚洲| 麻豆视频在线观看免费网站黄| 中文一区一区三区免费在线观 | 美女网站一区| 欧美精品一区二区三区精品| 欧美手机在线| 在线日韩视频| 日韩另类视频| 91久久亚洲| 四虎精品一区二区免费| 日韩精品成人| 久久久亚洲欧洲日产| 综合日韩av| 久久在线免费| 亚洲欧洲免费| 国产精品久久国产愉拍| 97精品一区| 久久久久久网| 一区福利视频| 国产欧美日韩一级| 麻豆一区在线| 99国产精品久久久久久久成人热| 1024精品久久久久久久久| 中文不卡在线| 国产一区二区三区国产精品| 国产精品mm| 国产精品99一区二区| 中文不卡在线| 日韩欧美视频专区| 模特精品在线| 成人影视亚洲图片在线| 蜜桃视频一区二区三区在线观看| 免费在线播放第一区高清av| 激情偷拍久久| 欧美综合社区国产| 99精品网站| 欧美1区二区| 午夜欧美视频| 国产一区国产二区国产三区| 午夜精品一区二区三区国产| 国产精品久久久久久久免费软件| 久久精品国产68国产精品亚洲| 欧美日韩亚洲一区二区三区在线 | 神马久久午夜| 国产剧情一区二区在线观看| 午夜久久免费观看| 成人一区而且| 日本视频一区二区| 国产在线日韩| 里番精品3d一二三区| 婷婷综合在线| 久久精品二区三区| 欧美精品国产一区| 国产精品日韩欧美一区| 国产99久久| 99精品一区| 日韩一区三区| 特黄毛片在线观看| 91日韩免费| 国产精品99在线观看| 精品久久影院| 国产精品99一区二区三| 韩国一区二区三区视频| 国产精品videossex久久发布| 免费在线视频一区| 99久久婷婷| 99热精品在线观看| 首页国产欧美久久| 亚洲欧洲av| 日本午夜精品久久久| 欧美va亚洲va日韩∨a综合色| 视频国产精品| 清纯唯美亚洲综合一区| 国产欧美一区二区色老头| 日韩av一区二| а√天堂8资源中文在线| 91精品啪在线观看国产18| 啪啪国产精品| 免费观看久久av| 石原莉奈在线亚洲三区| 在线看片一区| 精品日韩一区| 午夜精品影院| 国产视频一区二区在线播放| 久久这里只有| 久久久久国产精品一区二区| 中文精品在线| 久久亚洲黄色| 狠狠干成人综合网| 国产伦精品一区二区三区千人斩| 国产精品资源| 亚洲高清不卡| 国产亚洲字幕| 亚洲精品日韩久久| 免播放器亚洲| 久久国产欧美| 久久久男人天堂| 久久影院资源站| 国产精品jk白丝蜜臀av小说| 亚洲精品综合| 亚洲乱码视频| 蜜臀国产一区二区三区在线播放| 午夜国产一区二区| 午夜久久福利| 久久国产精品99国产| 99热精品在线| 国产视频一区免费看| 久久国产成人| 亚洲制服欧美另类| 日本国产亚洲| 国产日韩视频| 国产精品theporn| 精品视频在线观看网站| 久久97久久97精品免视看秋霞| 麻豆一区二区三区| 国产白浆在线免费观看| 日韩网站中文字幕| 婷婷综合网站| 日本不卡一二三区黄网| 欧美日韩va| 久久精品二区亚洲w码| 欧美精品高清| 爽爽淫人综合网网站| 日韩高清电影免费| 日韩av在线中文字幕| 日韩久久一区二区三区| 亚洲精品123区| 911精品国产| 欧美一区久久久| 99在线精品视频在线观看| 日本成人在线不卡视频| 捆绑调教美女网站视频一区| 日韩欧美少妇| 少妇精品久久久一区二区| 国产66精品| 午夜亚洲福利| 日韩电影二区| 国产亚洲久久| 91久久黄色| 国产精品激情| 国产精品任我爽爆在线播放| 日本亚洲最大的色成网站www| 国产精品va视频| 亚洲一区中文| 精品国产鲁一鲁****| 亚洲精选91| 亚洲先锋成人| 美女在线视频一区| 亚洲欧美网站在线观看| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 日韩视频精品在线观看| 欧美日韩1区| 在线亚洲成人| 国产美女高潮在线| 国产精品一区高清| 9久re热视频在线精品| 日韩综合在线| 国产精品久久久久久久久免费高清| 999久久久精品国产| 福利在线一区| 欧美成人精品一级| 美女毛片一区二区三区四区| 高清久久精品| 国产精品一区亚洲| 日韩精选在线| 亚洲精品影视| 亚洲网址在线观看| 久久亚洲国产精品一区二区| 亚洲天堂久久| 欧美aa国产视频| 91精品一区二区三区综合在线爱 | 丝袜亚洲另类欧美 | 激情综合婷婷| 国产成人精品一区二区三区视频 | 好看不卡的中文字幕| 99久久精品网| 亚洲大全视频| 亚洲美洲欧洲综合国产一区 | 久久久久九九精品影院| 国产精品宾馆|