日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程八锁问题

發(fā)布時(shí)間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程八锁问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

理解線程八鎖問題的關(guān)鍵:synchronized實(shí)現(xiàn)同步的基礎(chǔ),Java中的每一個(gè)對(duì)象都可以作為鎖。
具體表現(xiàn)為以下3種形式。

1.對(duì)于普通同步方法,鎖是當(dāng)前實(shí)例對(duì)象(this)2.對(duì)于靜態(tài)同步方法,鎖是當(dāng)前類的Class對(duì)象。 3.對(duì)于同步方法塊,鎖是Synchonized括號(hào)里配置的對(duì)象

一個(gè)對(duì)象里面如果有多個(gè)synchronized方法,某一個(gè)時(shí)刻內(nèi),只要一個(gè)線程去調(diào)用其中的一個(gè)synchronized方法了,其它的線程都只能等待,換句話說,某一個(gè)時(shí)刻內(nèi),只能有唯一一個(gè)線程去訪問這些synchronized方法鎖的是當(dāng)前對(duì)象this,被鎖定后,其它的線程都不能進(jìn)入到當(dāng)前對(duì)象的其它的synchronized方法。如果一個(gè)實(shí)例對(duì)象的非靜態(tài)同步方法獲取鎖后,該實(shí)例對(duì)象的其他非靜態(tài)同步方法必須等待獲取鎖的方法釋放鎖后才能獲取鎖,可是別的實(shí)例對(duì)象的非靜態(tài)同步方法因?yàn)楦搶?shí)例對(duì)象的非靜態(tài)同步方法用的是不同的鎖,所以無須等待該實(shí)例對(duì)象已獲取鎖的非靜態(tài)同步方法釋放鎖就可以獲取他們自己的鎖。所有的靜態(tài)同步方法用的也是同一把鎖——類對(duì)象本身,這兩把鎖是兩個(gè)不同的對(duì)象,所以靜態(tài)同步方法與非靜態(tài)同步方法之間是不會(huì)有競態(tài)條件的。但是一旦一個(gè)靜態(tài)同步方法獲取鎖后,其他的靜態(tài)同步方法都必須等待該方法釋放鎖后才能獲取鎖,而不管是同一個(gè)實(shí)例對(duì)象的靜態(tài)同步方法之間,還是不同的實(shí)例對(duì)象的靜態(tài)同步方法之間,只要它們同一個(gè)類的實(shí)例對(duì)象!

  • 場景一:
  • import java.util.concurrent.TimeUnit;/**1. 標(biāo)準(zhǔn)情況下 是先sendEmail() 還是先callPhone()?2. 答案:sendEmail3. 解釋:被 synchronized 修飾的方式,鎖的對(duì)象是方法的調(diào)用者4. 所以說這里兩個(gè)方法調(diào)用的對(duì)象是同一個(gè),先調(diào)用的先執(zhí)行!*/ public class LockDemo1 {public static void main(String[] args) throws InterruptedException {Phone1 phone1 = new Phone1();new Thread(()->{phone1.sendEmail();},"A").start();TimeUnit.SECONDS.sleep(3);new Thread(()->{phone1.callPhone();},"B").start();} } class Phone1{public synchronized void sendEmail(){System.out.println("senEmail");}public synchronized void callPhone(){System.out.println("callPhone");} }
  • 場景二:
  • import java.util.concurrent.TimeUnit;/**1. sendEmail()休眠三秒后 是先執(zhí)行sendEmail() 還是 callPhone()2. 答案: sendEmail3. 解釋:被 synchronized 修飾的方式,鎖的對(duì)象是方法的調(diào)用者4. 所以說這里兩個(gè)方法調(diào)用的對(duì)象是同一個(gè),先調(diào)用的先執(zhí)行!*/ public class LockDemo2 {public static void main(String[] args) throws InterruptedException {Phone2 phone2 = new Phone2();new Thread(()->{try {phone2.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(2); // 休眠2秒new Thread(()->{phone2.callPhone();},"B").start();} } class Phone2{public synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(3);System.out.println("sendEmail");}public synchronized void callPhone(){System.out.println("callPhone");} }
  • 場景三:
  • import java.util.concurrent.TimeUnit;/**1. 被synchronized 修飾的方式和普通方法 先執(zhí)行sendEmail() 還是 callPhone()2. 答案: callPhone3. 解釋:新增加的這個(gè)方法沒有 synchronized 修飾,不是同步方法,不受鎖的影響!*/ public class LockDemo3 {public static void main(String[] args) throws InterruptedException {Phone3 phone3 = new Phone3();new Thread(()->{try {phone3.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(2);new Thread(()->{phone3.callPhone();},"B").start();} } class Phone3{public synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("sendEmail");}// 沒有synchronized 沒有static 就是普通方式public void callPhone(){System.out.println("callPhone");} }
  • 場景四:
  • import java.util.concurrent.TimeUnit;/*** 被synchronized 修飾的不同方法 先執(zhí)行sendEmail() 還是callPhone()?* 答案:callPhone* 解釋:被synchronized 修飾的不同方法 鎖的對(duì)象是調(diào)用者* 這里鎖的是兩個(gè)不同的調(diào)用者,所有互不影響*/ public class LockDemo4 {public static void main(String[] args) throws InterruptedException {Phone4 phoneA = new Phone4();Phone4 phoneB = new Phone4();new Thread(()->{try {phoneA.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{phoneB.callPhone();},"B").start();} } class Phone4{public synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(3);System.out.println("sendEmail");}public synchronized void callPhone(){System.out.println("callPhone");} }
  • 場景五:
  • import java.util.concurrent.TimeUnit; /**1. 兩個(gè)靜態(tài)同步方法 都被synchronized 修飾 是先sendEmail() 還是callPhone()?2. 答案:sendEmial3. 解釋:只要方法被 static 修飾,鎖的對(duì)象就是 Class模板對(duì)象,這個(gè)則全局唯一!4. 所以說這里是同一個(gè)鎖,并不是因?yàn)閟ynchronized 這里程序會(huì)從上往下依次執(zhí)行*/ public class LockDemo5 {public static void main(String[] args) throws InterruptedException {Phone5 phone5 = new Phone5();new Thread(()->{try {phone5.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{phone5.callPhone();},"B").start();} } class Phone5{public static synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(3);System.out.println("sendEmail");}public static synchronized void callPhone(){System.out.println("callPhone");} }
  • 場景六:
  • import java.util.concurrent.TimeUnit;/**1. 被synchronized 修飾的普通方法和靜態(tài)方法 是先sendEmail() 還是 callPhone()?2. 答案:callPhone3. 解釋:只要被static修飾鎖的是class模板, 而synchronized 鎖的是調(diào)用的對(duì)象4. 這里是兩個(gè)鎖互不影響,按時(shí)間先后執(zhí)行*/ public class LockDemo6 {public static void main(String[] args) throws InterruptedException {Phone6 phone6 = new Phone6();new Thread(()->{try {phone6.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{phone6.callPhone();},"B").start();} } class Phone6{public static synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(3);System.out.println("sendEmail");}public synchronized void callPhone(){System.out.println("callPhone");} }
  • 場景七:
  • import java.util.concurrent.TimeUnit;/**1. 同被static+synchronized 修飾的兩個(gè)方法,是先sendEmail()還是callPhone()?2. 答案:sendEmail3. 解釋:只要方法被 static 修飾,鎖的對(duì)象就是 Class模板對(duì)象,這個(gè)則全局唯一4. 所以說這里是同一個(gè)鎖,并不是因?yàn)閟ynchronized*/ public class LockDemo7 {public static void main(String[] args) throws InterruptedException {Phone7 phoneA = new Phone7();Phone7 phoneB = new Phone7();new Thread(()->{try {phoneA.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{phoneB.callPhone();},"B").start();} } class Phone7{public static synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(3);System.out.println("sendEmail");}public static synchronized void callPhone(){System.out.println("callPhone");} }
  • 場景八:
  • import java.util.concurrent.TimeUnit;/**1. 一個(gè)被static+synchronized 修飾的方法和普通的synchronized方法,先執(zhí)行sendEmail()還是callPhone()?2. 答案:callPhone()3. 解釋: 只要被static 修飾的鎖的就是整個(gè)class模板4. 這里一個(gè)鎖的是class模板 一個(gè)鎖的是調(diào)用者 5. 所以鎖的是兩個(gè)對(duì)象 互不影響*/ public class LockDemo8 {public static void main(String[] args) throws InterruptedException {Phone8 phoneA = new Phone8();Phone8 phoneB = new Phone8();new Thread(()->{try {phoneA.sendEmail();} catch (InterruptedException e) {e.printStackTrace();}},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{phoneB.callPhone();},"B").start();} } class Phone8{public static synchronized void sendEmail() throws InterruptedException {TimeUnit.SECONDS.sleep(3);System.out.println("sendEmail");}public synchronized void callPhone(){System.out.println("callPhone");} }
  • 總結(jié):
  • 1、當(dāng)一個(gè)線程試圖訪問同步代碼塊時(shí),它首先必須得到鎖,退出或拋出異常時(shí)必須釋放鎖。2、Java 中的每一個(gè)對(duì)象都可以作為鎖;普通同步方法鎖 this,靜態(tài)同步方法鎖 Class,同步方法塊鎖括號(hào);3、只要鎖的對(duì)象不是同一個(gè),就直接按照線程執(zhí)行的快慢來決定;鎖的對(duì)象是同一個(gè),就按照線程進(jìn)入的先后順序決定。

    本文轉(zhuǎn)自:https://www.cnblogs.com/itiaotiao/p/12651573.html

    總結(jié)

    以上是生活随笔為你收集整理的线程八锁问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。