天天看點

java 死鎖代碼示例一、死鎖的産生條件二、死鎖代碼示例

一、死鎖的産生條件

  • 互斥使用:一個資源隻能配置設定給一個線程
  • 不可剝奪:資源隻能由占有者釋放,申請者不能強制剝奪
  • 請求保持:線程申請資源時,保持對原有資源的占有
  • 循環等待:存在一個程序等待隊列:{P1 , P2 , … , Pn}, 其中P1等待P2占有的資源,P2等待P3占有的資源,…,Pn等待P1占有的資源,形成一個程序等待環路

    代碼

  • 引用連結:https://www.jianshu.com/p/8cf78bf94f9d

二、死鎖代碼示例

自定義一個線程實作類,

package com.yunshi.synchronizedtest;

import org.hibernate.validator.internal.util.privilegedactions.NewInstance;

/**
 * 
 死鎖條件
互斥使用:一個資源隻能配置設定給一個線程
不可剝奪:資源隻能由占有者釋放,申請者不能強制剝奪
請求保持:線程申請資源時,保持對原有資源的占有
循環等待:存在一個程序等待隊列:{P1 , P2 , … , Pn}, 其中P1等待P2占有的資源,P2等待P3占有的資源,…,Pn等待P1占有的資源,形成一個程序等待環路
代碼

思路

定義兩個資源o1,o2
對象deadLock1占有資源o1,需要資源o2
對象deadLock2占有資源o2,需要資源o1
死鎖産生
 * @author Administrator
 *
 */
public class DeadLock implements Runnable{
	/**
	 * 定義兩個Object對象,模拟兩個線程占有的共享資源
	 * 此處需要注意的是,o1和o2 需要有static修飾,定義為靜态對象,這樣o1和o2才能在多個線程之間調用,才屬于共享資源,
	 * 沒有static修飾的話,DeadLock的每個執行個體對象中的 o1和o2 都将是獨立存在,互相隔離的,
	 */
	public static Object o1= new Object();
	public static Object o2= new Object();

	public int flag; // 屬性,又叫成員變量

	public DeadLock(int flag) {
		super();
		this.flag = flag;
	}

	@Override
	public void run() {
		if (flag==1) {
			// 代碼塊1
			synchronized (o1) {
				System.out.println("one-1");
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
				synchronized (o2) {
					System.out.println("one-2");
				}
			}
		}else {
			// 代碼塊2
			synchronized (o2) {
				System.out.println("two-1");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (o1) {
					System.out.println("two-2");
				}
			}
		}
	}

	public static void main(String[] args) {
		//建立線程1,flag 屬性值為1
		DeadLock deadLock1 = new DeadLock(1);
		//建立線程1,flag 屬性值為2
		DeadLock deadLock2 = new DeadLock(2);
		//啟動線程1和線程2
		/**
		 * 線程1啟動之後,調用順序是
		 * (1)執行代碼塊1,同時擷取到o1對象鎖,開始執行,線程沉睡1秒
		 * (2)接着去擷取o2的對象鎖,由于第二個線程先擷取的是o2的對象鎖,是以需要等待代碼塊2執行完畢,才能擷取到o2的對象鎖
		 */
		new Thread(deadLock1).start();
		/**
		 * 線程2啟動之後,調用順序是
		 * (1)執行代碼塊2,同時擷取到o2對象鎖,開始執行,線程沉睡1秒
		 * (2)接着去擷取o1的對象鎖,由于第一個線程先擷取的是o1的對象鎖,是以需要等待代碼塊1執行完畢,才能擷取到o1的對象鎖
		 */
		new Thread(deadLock2).start();
		/** 以上分析可得,線程一和線程二共用了對象o1和o2,各自都想要擷取對方的鎖,進而形成阻塞,一直等待下去,這種現象就是死鎖。*/
		
	}
	
}