java中synchronized Lock(本地同步)鎖的8種情況
Lock(本地同步)鎖的8種情況總結(jié)與說(shuō)明:
* 題目:
* 1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信 Email
* 2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信 Email
* 3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hello hello
* 4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 SMS
* 5.兩個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 Email
* 6.兩個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 Email
* 7.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 SMS
* 8.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 SMS
*
* lock1、2
* 一個(gè)對(duì)象里面如果有多個(gè)synchronized方法,某一時(shí)刻內(nèi),只要一個(gè)線程去調(diào)用其中的一個(gè)synchronized方法,
* 其他的線程都只能等待,換句話說(shuō),某一時(shí)刻內(nèi),只能有唯一一個(gè)線程去訪問(wèn)這些synchronized方法,
* 鎖的是當(dāng)前對(duì)象的this,被鎖定后,其它的線程都不能進(jìn)入到當(dāng)前對(duì)象的其它的synchronized方法
*
* lock3、4
* 加個(gè)普通的方法后和同步鎖無(wú)關(guān)
* 換成兩個(gè)對(duì)象后,不是同一把鎖了,情況立刻變化
*
* lock5、6
* 都換成靜態(tài)同步方法后,情況又變化(靜態(tài)鎖的是Class類對(duì)象)
* 若是普通同步方法,new this,具體的一部一部手機(jī),所有的普通同步方法用的都是同一把鎖----示例對(duì)象本身
* 若是靜態(tài)同步方法,static class,唯一的一個(gè)模板
* synchronized是實(shí)現(xiàn)同步的基礎(chǔ):Java中的每一個(gè)對(duì)象都可以作為鎖
* 具體表現(xiàn)為一下3種形式。
* 對(duì)于普通同步方法,鎖是當(dāng)前實(shí)例對(duì)象。它等同于 對(duì)于同步方法塊,鎖是synchronized括號(hào)里的配置的對(duì)象。
* 對(duì)于靜態(tài)同步方法,鎖是當(dāng)前類的Class類元信息
*
* lock7、8
* 當(dāng)一個(gè)線程試圖訪問(wèn)同步代碼塊時(shí)它首先必須得到鎖,退出或拋出異常時(shí)必須釋放鎖
*
* 所有的同步方法用的都是同一把鎖----實(shí)例對(duì)象本身,就是new出來(lái)的具體實(shí)例對(duì)象本身
* 也就是說(shuō)如果一個(gè)實(shí)例對(duì)象的普通同步方法獲取鎖后,該實(shí)例對(duì)象的其他普通同步方法必須等待獲取鎖的方法釋放鎖后才能獲得鎖
* 可是別的實(shí)例對(duì)象的普通同步方法因?yàn)楦搶?shí)例對(duì)象的普通同步方法用到是不同鎖,所以不用等待該實(shí)例對(duì)象已獲取鎖的普通
* 同步方法釋放鎖就可以獲取它們自己的鎖
*
* 所有的靜態(tài)同步方法用的也是同一把鎖----類對(duì)象本身,就是我們說(shuō)過(guò)的唯一模板Class
* 具體實(shí)例對(duì)象this和唯一模板Class,這兩把鎖是兩個(gè)不同的對(duì)象,所有靜態(tài)同步方法與普通同步方法之間是不會(huì)有競(jìng)態(tài)條件的,
* 但是一旦一個(gè)靜態(tài)同方法獲取鎖后,其他的靜態(tài)同步方法都必須等待該方法釋放鎖后才能獲取鎖。
lock1、2、3一個(gè)實(shí)例對(duì)象
lock4、5、6、7、8兩個(gè)實(shí)例對(duì)象
lock1
1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信?答案:Email
sendEmail()與sendSms()都是普通同步方法,都使用synchronized鎖
這里按方法調(diào)用順序,依次執(zhí)行,當(dāng)前synchronized鎖住的是同一個(gè)實(shí)例對(duì)象
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public synchronized void sendEmail() throws InterruptedException{ System.out.println("------------sendEmail"); } public synchronized void sendSms(){ System.out.println("------------sendSMS"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信 Email */ public class Lock8{ public static void main(String[] args) throws InterruptedException{ Phone phone=new Phone(); //線程A發(fā)送Email new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); //線程B發(fā)送短信 newThread(()->{ phone.sendSms(); },"B").start(); } }
lock2
2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信? 答案:Email
lock2是lock1的變形,其原理與lock1一致,synchronized鎖住的是同一個(gè)對(duì)象,必須等到第一個(gè)方法把鎖釋放后,第二個(gè)方法才能夠獲得鎖
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public synchronized void sendEmail()throwsInterruptedException{ //睡眠4秒種 TimeUnit.SECONDS.sleep(4); System.out.println("------------sendEmail"); } public synchronized void sendSms(){ System.out.println("------------sendSMS"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email */ public class Lock8{ public static void main(String[] args)throws InterruptedException{ //資源類 Phone phone=new Phone(); //線程A sendEmail newThread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); //這里保證線程A能夠執(zhí)行完 Thread.sleep(300); //線程B sendSms newThread(()->{ phone.sendSms(); },"B").start(); } }
結(jié)果:等待4秒中后出現(xiàn)sendEmail與sendSMS同時(shí)輸出
lock3
3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hello? 答案:hello
只有添加synchronized關(guān)鍵字的方法才會(huì)被synchronized鎖控制
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public synchronized void sendEmail()throws InterruptedException{ TimeUnit.SECONDS.sleep(4); System.out.println("------------sendEmail"); } public synchronized void sendSms(){ System.out.println("------------sendSMS"); } public void hello(){//未加synchronized System.out.println("hello"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email *3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hello hello */ public class Lock8{ public static void main(String[] args)throws InterruptedException{ Phone phone=new Phone(); //線程A調(diào)用sendEmail new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); //線程B調(diào)用普通方法hello new Thread(()->{ //phone.sendSms(); phone.hello(); },"B").start(); } }
結(jié)果:hello先輸出,4s后sendEmail再輸出
lock4
4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 ? 答案:SMS
不同實(shí)例對(duì)象,synchronized鎖住的是對(duì)應(yīng)的調(diào)用對(duì)象
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public synchronized void sendEmail()throws InterruptedException{ //睡眠4秒種 TimeUnit.SECONDS.sleep(4); System.out.println("------------sendEmail"); } public synchronized void sendSms(){ System.out.println("------------sendSMS"); } public void hello(){ System.out.println("hello"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email *3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hellohello *4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 SMS */ public class Lock8{ public static void main(String[] args)throws InterruptedException{ Phone phone=new Phone(); Phone phone2=new Phone(); //sychronized鎖定是當(dāng)前對(duì)象對(duì)應(yīng)的this,phone與phone2分別鎖的是自己的this //線程A使用實(shí)例phone調(diào)用sendEmail newThread(()->{ try{ //sendEmail方法中包含睡眠4秒種 phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); //線程B使用實(shí)例phone2調(diào)用sendSms newThread(()->{ phone2.sendSms(); //phone.hello(); },"B").start(); } }
結(jié)果:sendSMS先輸出,4s后sendEmail再輸出
lock5
5.兩個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信? 答案:Email
synchronized鎖靜態(tài)方法,實(shí)際是鎖住的類元信息,因?yàn)殪o態(tài)方法是隨類元信息的加載而保存到j(luò)vm的靜態(tài)區(qū),是所有實(shí)例創(chuàng)建的模板
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public static synchronized void sendEmail()throws InterruptedException{ TimeUnit.SECONDS.sleep(4); System.out.println("------------sendEmail"); } public static synchronized void sendSms(){ System.out.println("------------sendSMS"); } public void hello(){ System.out.println("hello"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email *3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hellohello *4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信SMS *5.兩個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 Email */ public class Lock8{ public static void main(String[] args)throws InterruptedException{ Phone phone=new Phone(); new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedException e){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); newThread(()->{ phone.sendSms(); },"B").start(); } }
結(jié)果:4秒種后,sendEmail率先輸出,sendSMS緊隨其后
lock6
6.兩個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信? 答案:Email
與lock5的運(yùn)行結(jié)果一致,當(dāng)前synchronized鎖住的是類元信息
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public static synchronized void sendEmail() throws InterruptedException{ TimeUnit.SECONDS.sleep(4); System.out.println("------------sendEmail"); } public static synchronized void sendSms(){ System.out.println("------------sendSMS"); } public void hello(){ System.out.println("hello"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email *3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hellohello *4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信SMS *5.兩個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信Email *6.兩個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信Email */ public class Lock8{ publicstaticvoidmain(String[]args)throwsInterruptedException{ Phone phone=new Phone(); Phone phone2=new Phone(); new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedException e){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); new Thread(()->{ //phone.sendSms(); phone2.sendSms(); //phone.hello(); },"B").start(); } }
結(jié)果:與lock5的運(yùn)行結(jié)果一致,sendEmail與sendSMS都是4s后進(jìn)行輸出,synchronized也是鎖住的類元信息
lock7
7.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印Email還是SMS? 答案:SMS
原理:普通同步方法,synchronized鎖住的是當(dāng)前實(shí)例對(duì)象,當(dāng)前實(shí)例對(duì)象存在于jvm的堆內(nèi)存區(qū)
靜態(tài)同步方法,synchronized鎖住的是當(dāng)前類的類元信息,存在于jvm元空間的靜態(tài)區(qū)中
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ //靜態(tài)同步方法 public static synchronized void sendEmail()throws InterruptedException{ TimeUnit.SECONDS.sleep(4); System.out.println("------------sendEmail"); } //普通同步方法 public synchronized void sendSms(){//無(wú)static System.out.println("------------sendSMS"); } public void hello(){ System.out.println("hello"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email *3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hellohello *4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信SMS *5.兩個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信Email *6.兩個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信Email *7.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信 SMS */ public class Lock8{ public static void main(String[] args) throws InterruptedException{ Phonephone=newPhone(); Phonephone2=newPhone(); newThread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); newThread(()->{ phone.sendSms(); //phone2.sendSms(); //phone.hello(); },"B").start(); } }
結(jié)果:sendSMS先輸出,4s后sendEmail再輸出
lock8
8.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信? 答案:SMS
原理:與lock7一致
package day02_lam; import java.util.concurrent.TimeUnit; class Phone{ public static synchronized void sendEmail()throwsInterruptedException{ TimeUnit.SECONDS.sleep(3); System.out.println("------------sendEmail"); } public synchronized void sendSms(){ System.out.println("------------sendSMS"); } public void hello(){ System.out.println("hello"); } } /** *題目: *1.標(biāo)準(zhǔn)訪問(wèn),請(qǐng)問(wèn)是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請(qǐng)問(wèn)是先打印郵件還是短信Email *3.新增普通的hello方法,請(qǐng)問(wèn)先打印郵件還是hellohello *4.兩部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信SMS *5.兩個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信Email *6.兩個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信Email *7.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,1部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信SMS *8.一個(gè)普通同步方法,一個(gè)靜態(tài)同步方法,2部手機(jī),請(qǐng)問(wèn)先打印郵件還是短信SMS */ public class Lock8{ publicstaticvoidmain(String[]args)throwsInterruptedException{ Phone phone=new Phone(); Phone phone2=new Phone(); new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); new Thread(()->{ //phone.sendSms(); phone2.sendSms(); //phone.hello(); },"B").start(); } }
結(jié)果:運(yùn)行結(jié)果與lock7一致,sendSMS先輸出,4s后sendEmail再輸出
到此這篇關(guān)于java中synchronized Lock(本地同步)鎖的8種情況的文章就介紹到這了,更多相關(guān) synchronized Lock鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java并發(fā)編程之阻塞隊(duì)列(BlockingQueue)詳解
- Java中雙重檢查鎖(double checked locking)的正確實(shí)現(xiàn)
- Java并發(fā)編程之ReentrantLock實(shí)現(xiàn)原理及源碼剖析
- 詳解Java多線程tryLock()方法使用
- java并發(fā)編程工具類PriorityBlockingQueue優(yōu)先級(jí)隊(duì)列
- Java中提供synchronized后為什么還要提供Lock
- Java并發(fā)編程之StampedLock鎖介紹
- Java中l(wèi)ock和tryLock及l(fā)ockInterruptibly的區(qū)別
相關(guān)文章
java 轉(zhuǎn)發(fā)和重定向區(qū)別及實(shí)例代碼
這篇文章主要介紹了java 轉(zhuǎn)發(fā)和重定向區(qū)別及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-11-11基于jenkins實(shí)現(xiàn)發(fā)布node.js項(xiàng)目
這篇文章主要介紹了基于jenkins實(shí)現(xiàn)發(fā)布node.js項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07SpringBoot DBUnit 單元測(cè)試(小結(jié))
這篇文章主要介紹了SpringBoot DBUnit 單元測(cè)試(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Spring如何使用PropertyPlaceholderConfigurer讀取文件
這篇文章主要介紹了Spring如何使用PropertyPlaceholderConfigurer讀取文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12java實(shí)現(xiàn)簡(jiǎn)單的ATM項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的ATM項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10解決RabbitMq消息隊(duì)列Qos?Prefetch消息堵塞問(wèn)題
這篇文章主要為大家介紹了關(guān)于如何解決解決RabbitMq?Qos?Prefetch消息堵塞的問(wèn)題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-01-01Java中多種循環(huán)Map的常見(jiàn)方式詳解
Java中的Map是一種鍵值對(duì)存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu),其中每個(gè)鍵都唯一,與一個(gè)值相關(guān)聯(lián),下面這篇文章主要給大家介紹了關(guān)于Java中多種循環(huán)Map的常見(jiàn)方式,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2024-01-01