java執行緒安全之synchronized鎖重入及出現異常鎖自動釋放(五)
阿新 • • 發佈:2019-01-03
科技快訊
11月16日下午訊息,以“Bring AI to Life”為主題的2017百度世界大會今天在北京國貿大酒店和北京嘉裡大酒店舉行。愛奇藝創始人兼CEO龔宇在大會上發表了主題為“愛奇藝·更懂娛樂”的主題演講,龔宇表示愛奇藝對於科技的重視與百度的AI創新基因一脈相承。
synchronized鎖重入
關鍵字synchronized擁有鎖重入的功能,也就是在使用synchronized時,當一個執行緒得到了一個物件的鎖後,再次請求此物件時是可以再次得到該物件的鎖。
案例:
public class SyncDubbo {
static class Main {
public int i = 10;
public synchronized void operationSup(){
try {
i--;
System.out.println("Main print i = " + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Sub extends Main {
public synchronized void operationSub(){
try {
while(i > 0) {
i--;
System.out.println("Sub print i = " + i);
Thread.sleep(1000);
this.operationSup();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Sub sub = new Sub();
sub.operationSub();
}
});
t1.start();
}
}
列印結果:
Sub print i = 9
Main print i = 8
Sub print i = 7
Main print i = 6
Sub print i = 5
Main print i = 4
Sub print i = 3
Main print i = 2
Sub print i = 1
Main print i = 0
出現異常,鎖自動釋放
案例:
public class SyncException {
private int i = 0;
public synchronized void operation(){
while(true){
try {
i++;
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " , i = " + i);
if(i == 5){//模擬業務邏輯出現異常,丟擲異常,在方法丟擲異常的時候會自動解鎖
throw new RuntimeException();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final SyncException se = new SyncException();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
se.operation();
}
},"t1");
t1.start();
}
}
列印結果:
t1 , i = 1
t1 , i = 2
t1 , i = 3
t1 , i = 4
t1 , i = 5
Exception in thread "t1" java.lang.RuntimeException
at cn.hfbin.base.sync005.SyncException.operation(SyncException.java:18)
at cn.hfbin.base.sync005.SyncException$1.run(SyncException.java:32)
at java.lang.Thread.run(Thread.java:745)
說明
對於web應用程式,異常釋放鎖的情況,如果不及時處理,很可能對你的應用程式業務邏輯產生嚴重的錯誤,比如你現在執行一個佇列任務,很多物件都去在等待第一個物件正確執行完畢再去釋放鎖,但是第一個物件由於異常的出現,導致業務邏輯沒有正常執行完畢,就釋放了鎖,那麼可想而知後續的物件執行的都是錯誤的邏輯。所以這一點一定要引起注意,在編寫程式碼的時候,一定要考慮周全。