前言:
在實現一個死鎖時,可能由於String s = " " 與 String s = new String( " " ) 的不同,造成死鎖的的形成也有很大的不同,應該需要了解下其各自的特性;
上代碼:
public class Dead {
private String s1 = "s1";
private String s2 = "s2";
private String s3 = new String("s1");
private String s4 = new String("s2");
public void get1() {
synchronized (s1) {
System.out.println(Thread.currentThread().getName() + " 獲取了s1鎖。。。。");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s2) {
System.out.println(Thread.currentThread().getName() + " 獲取了s2鎖。。。。");
}
}
}
public void get2() {
synchronized (s2) {
System.out.println(Thread.currentThread().getName() + " 獲取了s2鎖。。。。");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s1) {
System.out.println(Thread.currentThread().getName() + " 獲取了s1鎖。。。。");
}
}
}
public void get3() {
synchronized (s3) {
System.out.println(Thread.currentThread().getName() + " 獲取了s3鎖。。。。");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s4) {
System.out.println(Thread.currentThread().getName() + " 獲取了s4鎖。。。。");
}
}
}
public void get4() {
synchronized (s4) {
System.out.println(Thread.currentThread().getName() + " 獲取了s4鎖。。。。");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s3) {
System.out.println(Thread.currentThread().getName() + " 獲取了s3鎖。。。。");
}
}
}
public static void main(String[] args) {
final Dead d = new Dead();
final Dead d1 = new Dead();
new Thread(new Runnable() {
public void run() {
System.out.println("================String s = \"\" ==================================");
d.get1();
}
}).start();
new Thread(new Runnable() {
public void run() {
d1.get2();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("==================String s = new String(\"\")======================");
d.get3();
}
}).start();
new Thread(new Runnable() {
public void run() {
d1.get4();
}
}).start();
}
}
輸出結果:
================String s = "" ==================================
Thread-0 獲取了s1鎖。。。。
Thread-1 獲取了s2鎖。。。。
==================String s = new String("")======================
Thread-2 獲取了s3鎖。。。。
Thread-3 獲取了s4鎖。。。。
Thread-2 獲取了s4鎖。。。。
Thread-3 獲取了s3鎖。。。。
總結:
1、String s1 = "s1"; 是將字符串放到常量池中的,然後在 Dead 堆對象中存放的是常量池中對應字符串的地址,所以即使 new 兩個對象,它們 的加鎖對象都是相同的,所以就會產生死鎖。
2、String s3 = new String("s1"); 這是直接在堆中new 的對象,然後在 Dead 堆對象中存放的是字符串在堆中的地址,new的兩個字符串在堆中一定是不同的,所以它們的加鎖對象是不同的,所以就不會產生死鎖;