您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關java中synchronized Lock的8種情況分別是怎樣的,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
Lock(本地同步)鎖的8種情況總結與說明:
* 題目:
* 1.標準訪問,請問是先打印郵件還是短信 Email
* 2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信 Email
* 3.新增普通的hello方法,請問先打印郵件還是hello hello
* 4.兩部手機,請問先打印郵件還是短信 SMS
* 5.兩個靜態同步方法,1部手機,請問先打印郵件還是短信 Email
* 6.兩個靜態同步方法,2部手機,請問先打印郵件還是短信 Email
* 7.一個普通同步方法,一個靜態同步方法,1部手機,請問先打印郵件還是短信 SMS
* 8.一個普通同步方法,一個靜態同步方法,2部手機,請問先打印郵件還是短信 SMS
*
* lock1、2
* 一個對象里面如果有多個synchronized方法,某一時刻內,只要一個線程去調用其中的一個synchronized方法,
* 其他的線程都只能等待,換句話說,某一時刻內,只能有唯一一個線程去訪問這些synchronized方法,
* 鎖的是當前對象的this,被鎖定后,其它的線程都不能進入到當前對象的其它的synchronized方法
*
* lock3、4
* 加個普通的方法后和同步鎖無關
* 換成兩個對象后,不是同一把鎖了,情況立刻變化
*
* lock5、6
* 都換成靜態同步方法后,情況又變化(靜態鎖的是Class類對象)
* 若是普通同步方法,new this,具體的一部一部手機,所有的普通同步方法用的都是同一把鎖----示例對象本身
* 若是靜態同步方法,static class,唯一的一個模板
* synchronized是實現同步的基礎:Java中的每一個對象都可以作為鎖
* 具體表現為一下3種形式。
* 對于普通同步方法,鎖是當前實例對象。它等同于 對于同步方法塊,鎖是synchronized括號里的配置的對象。
* 對于靜態同步方法,鎖是當前類的Class類元信息
*
* lock7、8
* 當一個線程試圖訪問同步代碼塊時它首先必須得到鎖,退出或拋出異常時必須釋放鎖
*
* 所有的同步方法用的都是同一把鎖----實例對象本身,就是new出來的具體實例對象本身
* 也就是說如果一個實例對象的普通同步方法獲取鎖后,該實例對象的其他普通同步方法必須等待獲取鎖的方法釋放鎖后才能獲得鎖
* 可是別的實例對象的普通同步方法因為跟該實例對象的普通同步方法用到是不同鎖,所以不用等待該實例對象已獲取鎖的普通
* 同步方法釋放鎖就可以獲取它們自己的鎖
*
* 所有的靜態同步方法用的也是同一把鎖----類對象本身,就是我們說過的唯一模板Class
* 具體實例對象this和唯一模板Class,這兩把鎖是兩個不同的對象,所有靜態同步方法與普通同步方法之間是不會有競態條件的,
* 但是一旦一個靜態同方法獲取鎖后,其他的靜態同步方法都必須等待該方法釋放鎖后才能獲取鎖。
lock1、2、3一個實例對象
lock4、5、6、7、8兩個實例對象
1.標準訪問,請問是先打印郵件還是短信?答案:Email
sendEmail()與sendSms()都是普通同步方法,都使用synchronized鎖
這里按方法調用順序,依次執行,當前synchronized鎖住的是同一個實例對象
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.標準訪問,請問是先打印郵件還是短信 Email */ public class Lock8{ public static void main(String[] args) throws InterruptedException{ Phone phone=new Phone(); //線程A發送Email new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); //線程B發送短信 newThread(()->{ phone.sendSms(); },"B").start(); } }
2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信? 答案:Email
lock2是lock1的變形,其原理與lock1一致,synchronized鎖住的是同一個對象,必須等到第一個方法把鎖釋放后,第二個方法才能夠獲得鎖
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.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信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能夠執行完 Thread.sleep(300); //線程B sendSms newThread(()->{ phone.sendSms(); },"B").start(); } }
結果:等待4秒中后出現sendEmail與sendSMS同時輸出
3.新增普通的hello方法,請問先打印郵件還是hello? 答案:hello
只有添加synchronized關鍵字的方法才會被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.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信Email *3.新增普通的hello方法,請問先打印郵件還是hello hello */ public class Lock8{ public static void main(String[] args)throws InterruptedException{ Phone phone=new Phone(); //線程A調用sendEmail new Thread(()->{ try{ phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); //線程B調用普通方法hello new Thread(()->{ //phone.sendSms(); phone.hello(); },"B").start(); } }
結果:hello先輸出,4s后sendEmail再輸出
4.兩部手機,請問先打印郵件還是短信 ? 答案:SMS
不同實例對象,synchronized鎖住的是對應的調用對象
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.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信Email *3.新增普通的hello方法,請問先打印郵件還是hellohello *4.兩部手機,請問先打印郵件還是短信 SMS */ public class Lock8{ public static void main(String[] args)throws InterruptedException{ Phone phone=new Phone(); Phone phone2=new Phone(); //sychronized鎖定是當前對象對應的this,phone與phone2分別鎖的是自己的this //線程A使用實例phone調用sendEmail newThread(()->{ try{ //sendEmail方法中包含睡眠4秒種 phone.sendEmail(); }catch(InterruptedExceptione){ e.printStackTrace(); } },"A").start(); Thread.sleep(300); //線程B使用實例phone2調用sendSms newThread(()->{ phone2.sendSms(); //phone.hello(); },"B").start(); } }
結果:sendSMS先輸出,4s后sendEmail再輸出
5.兩個靜態同步方法,1部手機,請問先打印郵件還是短信? 答案:Email
synchronized鎖靜態方法,實際是鎖住的類元信息,因為靜態方法是隨類元信息的加載而保存到jvm的靜態區,是所有實例創建的模板
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.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信Email *3.新增普通的hello方法,請問先打印郵件還是hellohello *4.兩部手機,請問先打印郵件還是短信SMS *5.兩個靜態同步方法,1部手機,請問先打印郵件還是短信 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(); } }
結果:4秒種后,sendEmail率先輸出,sendSMS緊隨其后
6.兩個靜態同步方法,2部手機,請問先打印郵件還是短信? 答案:Email
與lock5的運行結果一致,當前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.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信Email *3.新增普通的hello方法,請問先打印郵件還是hellohello *4.兩部手機,請問先打印郵件還是短信SMS *5.兩個靜態同步方法,1部手機,請問先打印郵件還是短信Email *6.兩個靜態同步方法,2部手機,請問先打印郵件還是短信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(); } }
結果:與lock5的運行結果一致,sendEmail與sendSMS都是4s后進行輸出,synchronized也是鎖住的類元信息
7.一個普通同步方法,一個靜態同步方法,1部手機,請問先打印Email還是SMS? 答案:SMS
原理:普通同步方法,synchronized鎖住的是當前實例對象,當前實例對象存在于jvm的堆內存區
靜態同步方法,synchronized鎖住的是當前類的類元信息,存在于jvm元空間的靜態區中
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 synchronized void sendSms(){//無static System.out.println("------------sendSMS"); } public void hello(){ System.out.println("hello"); } } /** *題目: *1.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信Email *3.新增普通的hello方法,請問先打印郵件還是hellohello *4.兩部手機,請問先打印郵件還是短信SMS *5.兩個靜態同步方法,1部手機,請問先打印郵件還是短信Email *6.兩個靜態同步方法,2部手機,請問先打印郵件還是短信Email *7.一個普通同步方法,一個靜態同步方法,1部手機,請問先打印郵件還是短信 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(); } }
結果:sendSMS先輸出,4s后sendEmail再輸出
8.一個普通同步方法,一個靜態同步方法,2部手機,請問先打印郵件還是短信? 答案: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.標準訪問,請問是先打印郵件還是短信Email *2.email方法新增暫停4秒鐘,請問是先打印郵件還是短信Email *3.新增普通的hello方法,請問先打印郵件還是hellohello *4.兩部手機,請問先打印郵件還是短信SMS *5.兩個靜態同步方法,1部手機,請問先打印郵件還是短信Email *6.兩個靜態同步方法,2部手機,請問先打印郵件還是短信Email *7.一個普通同步方法,一個靜態同步方法,1部手機,請問先打印郵件還是短信SMS *8.一個普通同步方法,一個靜態同步方法,2部手機,請問先打印郵件還是短信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(); } }
結果:運行結果與lock7一致,sendSMS先輸出,4s后sendEmail再輸出
以上就是java中synchronized Lock的8種情況分別是怎樣的,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。