站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖

        相關免費學習推薦:java基礎教程

        8鎖問題演示

        1.標準訪問

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public synchronized void sendEmail() throws Exception{ 		System.out.println("***sendEmail"); 	} 	public synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				phone.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖
        標準訪問,先打印郵件還是短信.
        不一定誰先被打印。取決于CPU的執(zhí)行情況.激活他們的是main線程,后面誰先被調(diào)度,不知道。
        為了保證效果,我們在A和B的代碼之間加thread.sleep(100).此時,可以確保A先被打印。
        解釋:
        只要一個資源類里面,不管它有多少個同步方法,只要一個線程先訪問了資源類里面的任何一個同步方法,那么它鎖的不是這一個方法,鎖的是該方法所在的整個資源類。也就是說,鎖的是對象。它鎖的不是當前的方法。
        也就是說,這些synchoronized的方法都屬于同一個資源類里面,鎖的是整個資源類。

        2.在郵件方法中暫停4秒,請問先打印郵件還是短信

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				phone.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        先打印郵件。同步方法獲取的phone對象鎖,sleep不會釋放鎖。到了時間會立即執(zhí)行。所以先打印郵件方法
        解釋:
        它與問題1類似。
        只要一個資源類里面,不管它有多少個同步方法,只要一個線程先訪問了資源類里面的任何一個同步方法,那么它鎖的不是這一個方法,鎖的是該方法所在的整個資源類。也就是說,鎖的是對象。它鎖的不是當前的方法。
        舉個例子:我和班長要用同一個手機打電話,我肯定要等班長打完電話才能接著打。班長用的過程中停網(wǎng)了一段時間,那我也只能等班長打完。

        3.新增普通sayHello方法,請問先打印郵件還是hello

        先打印hello

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	} 	public void sayHello(){ 		System.out.println("***sayHello"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				//phone.sendSMS(); 				phone.sayHello(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖
        解釋:加個普通方法后發(fā)現(xiàn)和同步鎖無關。因此它無需等待同步鎖釋放。
        這里可以舉一個例子。班長用它的手機要打電話。而我要向班長借手機充電線,這兩個不互斥,因此可以在班長打電話完之前就借走充電線。

        4.兩部手機,請問先打印郵件還是短信

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	} 	public void sayHello(){ 		System.out.println("***sayHello"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		Phone phone2=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				//phone.sendSMS(); 				//phone.sayHello(); 				phone2.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖

        解釋:這里可以舉一個例子,班長用它的手機法郵件。我用我自己的手機打電話。那么誰先誰后就沒有關系。

        5.兩個靜態(tài)同步方法,同一部手機,請問先打印郵件還是短信

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public static synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public static synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	} 	public void sayHello(){ 		System.out.println("***sayHello"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		Phone phone2=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				phone.sendSMS(); 				//phone.sayHello(); 				//phone2.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖
        解釋:可以與問題6一起分析

        6.兩個靜態(tài)同步方法,兩部手機,請問先打印郵件還是短信

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public static synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public static synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	} 	public void sayHello(){ 		System.out.println("***sayHello"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		Phone phone2=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				//phone.sendSMS(); 				//phone.sayHello(); 				phone2.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖
        解析:
        static屬于一個類。也就說,他不屬于當前對象this的一個獨立的個體。而是屬于全局的class。這就要考慮對象鎖和全局鎖的區(qū)別。全局鎖即類鎖。此時不管是一個phone還是多個phone都來自于同一個類Phone類。現(xiàn)在不管你鎖到了哪個對象,我都要等他釋放完了這個鎖才能使用。

        7.1個靜態(tài)同步方法,1個普通同步方法,同一部手機,請問先打印郵件還是短信

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public static synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	} 	public void sayHello(){ 		System.out.println("***sayHello"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		Phone phone2=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				phone.sendSMS(); 				//phone.sayHello(); 				//phone2.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖
        一個靜態(tài),一個普通。鎖的是同一部手機。靜態(tài)方法鎖的是Class.相當于我們鎖了一個校門,一個是普通同步方法,鎖的是當前對象。比如教師普通的們。鎖的對象不一樣。就不沖突

        8.1個靜態(tài)同步方法,1個普通同步方法,兩部手機,請問先打印郵件還是短信

        /*手機類可以發(fā)郵件和發(fā)短信*/class Phone{ 	public static synchronized void sendEmail() throws Exception{ 		TimeUnit.SECONDS.sleep(4);		//表示暫停4秒,它是一個枚舉類型 		System.out.println("***sendEmail"); 	} 	public synchronized void sendSMS() throws Exception{ 		System.out.println("***sendSMS"); 	} 	public void sayHello(){ 		System.out.println("***sayHello"); 	}}public class Lock8Demo { 	public static void main(String[] args) throws InterruptedException { 		//創(chuàng)建一個資源類 		Phone phone=new Phone(); 		Phone phone2=new Phone(); 		new Thread(()->{ 			try { 				phone.sendEmail(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"A").start(); 		Thread.sleep(100); 		new Thread(()->{ 			try { 				//phone.sendSMS(); 				//phone.sayHello(); 				phone2.sendSMS(); 			} catch (Exception e) { 				// TODO Auto-generated catch block 				e.printStackTrace(); 			} 		},"B").start(); 	}}

        Java介紹八鎖問題帶你徹底理解對象鎖和類鎖

        解釋:這個跟上面是一樣的。

        8鎖理論解釋

        1.一個對象里面如果有多個syncrhonized方法,某一時刻內(nèi),只要有一個線程去調(diào)用其中的一個synchronized方法了,其他的線程都只能等待,換句話說,某一時刻內(nèi),只能有唯一一個線程去訪問這些synchronized方法。
        鎖的是當前對象this,被鎖定后,其他的線程都不能進入到當前對象的其他synchronized方法

        加個普通方法后發(fā)現(xiàn)和同步鎖無關。
        換乘兩個對象后,不是同一把鎖了,情況立刻發(fā)生變化。
        都換成靜態(tài)同步方法后,情況立刻變化
        所有的非靜態(tài)同步方法用的都是同一把鎖——實例對象本身

        2.synchronized實現(xiàn)同步的基礎:java中的每個對象都可以作為鎖。
        具體表現(xiàn)為以下3種形式:

        1. 對于普通同步方法,鎖是當前實例對象
        2. 對于同步方法塊,鎖是synchronized括號里面配置的對象。
          比如在方法里寫
          synchronized(this){
          }
        3. 對于靜態(tài)同步方法,鎖是當前類的Class對象。

        當一個進程試圖訪問同步代碼塊時,它首先必須得到鎖,退出或拋出異常必須釋放鎖。
        也就是說一個實例對象的非靜態(tài)同步方法獲取鎖后,該實例對象的其他非靜態(tài)同步方法必須等待獲取鎖的方法釋放鎖后才能獲取鎖。可是別的實例對象的非靜態(tài)同步方法因為跟該實例對象的非靜態(tài)同步方法用的是不同的鎖,所以無需等待該實例對象已獲取鎖的非靜態(tài)同步方法釋放鎖就可以獲取他們自己的鎖。

        所有的靜態(tài)同步方法用的也是同一把鎖—–類對象本身。
        這兩把鎖是兩個不同的對象,所以靜態(tài)同步方法與非靜態(tài)同步方法之間是不會有競態(tài)條件的。(問題78)。即一個鎖class,一個鎖this,兩者不沖突。
        但是一旦一個靜態(tài)同步方法獲取鎖后,其他的靜態(tài)同步方法都必須等待該方法釋放鎖后才能獲取鎖。而不管是同一個實例對象的靜態(tài)方法之間,還是不同的實例對象的靜態(tài)同步方法之間,只要它們同一個類的實例對象。(問題56)

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 亚洲精品无码久久久| 日韩精品无码久久久久久| 欧美成人精品高清在线播放| 国产精品扒开腿做爽爽爽视频| 精品午夜福利1000在线观看| 久久精品一区二区| 精品久久久久久国产潘金莲| 日韩欧美一区二区三区中文精品 | 伊人精品视频在线| 国产69精品久久久久99| 国产成人精品视频一区二区不卡 | 2020亚洲男人天堂精品| 最新国产精品精品视频| 精品国产成人国产在线观看| 老司机国内精品久久久久| 日韩精品无码中文字幕一区二区 | 久久精品国产亚洲Aⅴ蜜臀色欲| 777久久精品一区二区三区无码| 国产精品怡红院永久免费| 精品午夜福利在线观看| 亚洲Av无码精品色午夜 | 99精品久久久久久久婷婷| 精品国产免费一区二区三区香蕉| 久久99国产精品尤物| 无码囯产精品一区二区免费| 香蕉国产精品麻豆亚洲欧美日韩精品自拍欧美v国 | 99久久国产综合精品网成人影院| 欧美成人精品高清在线观看| 综合在线视频精品专区| 亚洲欧洲精品成人久久曰影片 | 亚洲精品成人久久久| 色偷偷88欧美精品久久久| 四虎国产精品永久地址入口| 精品久久久久久国产牛牛app| 国产高清在线精品一区二区| 中国精品videossex中国高清| 热久久这里只有精品| 亚洲精品小视频| 国产精品国产三级国产| 国产一级精品高清一级毛片| 精品久久久无码中文字幕天天 |