死鎖中共享資源String s = " " 與 String s = new String( " " ) 的不同

前言:

在實現一個死鎖時,可能由於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的兩個字符串在堆中一定是不同的,所以它們的加鎖對象是不同的,所以就不會產生死鎖;

發佈了22 篇原創文章 · 獲贊 33 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章