生活随笔
收集整理的這篇文章主要介紹了
线程八锁问题
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
理解線程八鎖問題的關(guān)鍵:synchronized實(shí)現(xiàn)同步的基礎(chǔ),Java中的每一個(gè)對象都可以作為鎖。
具體表現(xiàn)為以下3種形式。
1.對于普通同步方法,鎖是當(dāng)前實(shí)例對象
(this)。
2.對于靜態(tài)同步方法,鎖是當(dāng)前類的Class對象。
3.對于同步方法塊,鎖是Synchonized括號里配置的對象
一個(gè)對象里面如果有多個(gè)synchronized方法,某一個(gè)時(shí)刻內(nèi),只要一個(gè)線程去調(diào)用其中的一個(gè)synchronized方法了,其它的線程都只能等待,換句話說,某一個(gè)時(shí)刻內(nèi),只能有唯一一個(gè)線程去訪問這些synchronized方法鎖的是當(dāng)前對象this,被鎖定后,其它的線程都不能進(jìn)入到當(dāng)前對象的其它的synchronized方法。如果一個(gè)實(shí)例對象的非靜態(tài)同步方法獲取鎖后,該實(shí)例對象的其他非靜態(tài)同步方法必須等待獲取鎖的方法釋放鎖后才能獲取鎖,可是別的實(shí)例對象的非靜態(tài)同步方法因?yàn)楦搶?shí)例對象的非靜態(tài)同步方法用的是不同的鎖,所以無須等待該實(shí)例對象已獲取鎖的非靜態(tài)同步方法釋放鎖就可以獲取他們自己的鎖。所有的靜態(tài)同步方法用的也是同一把鎖——類對象本身,這兩把鎖是兩個(gè)不同的對象,所以靜態(tài)同步方法與非靜態(tài)同步方法之間是不會(huì)有競態(tài)條件的。但是一旦一個(gè)靜態(tài)同步方法獲取鎖后,其他的靜態(tài)同步方法都必須等待該方法釋放鎖后才能獲取鎖,而不管是同一個(gè)實(shí)例對象的靜態(tài)同步方法之間,還是不同的實(shí)例對象的靜態(tài)同步方法之間,只要它們同一個(gè)類的實(shí)例對象!
場景一:
import java
.util
.concurrent
.TimeUnit
;
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
;
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); 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
;
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");}public void callPhone(){System
.out
.println("callPhone");}
}
場景四:
import java
.util
.concurrent
.TimeUnit
;
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
;
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
;
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
;
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
;
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è)對象都可以作為鎖;普通同步方法鎖
this,靜態(tài)同步方法鎖 Class,同步方法塊鎖括號;
3、只要鎖的對象不是同一個(gè),就直接按照線程執(zhí)行的快慢來決定;鎖的對象是同一個(gè),就按照線程進(jìn)入的先后順序決定。
本文轉(zhuǎn)自:https://www.cnblogs.com/itiaotiao/p/12651573.html
總結(jié)
以上是生活随笔為你收集整理的线程八锁问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。