突發奇想-怎麼寫一個死鎖?

剛把手頭上的項目代碼擼完,閒來看看博客,而後就看到了線程這塊的東西。以前有簡單的記錄過線程和進行的零碎知識。
JAVA基礎知識系列---進程、線程安全安全

看着看着就想着怎麼能寫一個死鎖呢,打開eclipse,忽然感受無從下手;以前都是一直在解決阻塞、死鎖這些問題,如今反過來去寫一個死鎖感受有點莫名奇妙。。。bash

ok,寫一個死鎖就要有一種場景,而且知足死鎖的條件。app

  • 互斥條件:一個資源每次只能被一個進程使用。
  • 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放
  • 不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
  • 循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。

首先要有競爭的資源,而且兩個線程要同時都在等待對方釋放資源。那咱們先弄兩個資源:eclipse

Object lock=new Object();
Object lock2=new Object();
複製代碼

而後有兩個線程:ide

Tr1 tr1=new Tr1(lock, lock2);
Tr2 tr2=new Tr2(lock, lock2);
		
Thread t1=new Thread(tr1);
Thread t2=new Thread(tr2);
複製代碼

啓動:post

t1.start();
t2.start();
複製代碼

那麼對於lock,lock2怎麼再線程內部產生競爭關係呢?來看代碼:this

package com.glmapper.base.synchronize;

public class Tr1 implements Runnable {
	
	Object lock;
	Object lock2;

	public Tr1(Object lock,Object lock2){
		this.lock= lock;
		this.lock2= lock2;
	}
	@Override
	public void run() {
	    //獲取lock
		synchronized (lock) {
			System.out.println(Thread.currentThread().getName()+"獲取了lock鎖");
			try {
				Thread.sleep(3000);
			} catch (Exception e) {
			}
			//獲取lock2
			synchronized (lock2) {
				System.out.println(Thread.currentThread().getName()+"獲取了lock2鎖");
			}
		}
		
	}
}


public class Tr2 implements Runnable {
	
	Object lock;
	Object lock2;

	public Tr2(Object lock,Object lock2){
		this.lock= lock;
		this.lock2= lock2;
	}
	@Override
	public void run() {
	    //獲取lock2
		synchronized (lock2) {
			System.out.println(Thread.currentThread().getName()+"獲取了lock2鎖");
			try {
				Thread.sleep(3000);
			} catch (Exception e) {
			}
			//獲取lock
			synchronized (lock) {
				System.out.println(Thread.currentThread().getName()+"獲取了lock鎖");
			}
		}
		
	}
}

複製代碼

分析一下:當線程1獲取lock時,線程2獲取了lock2鎖;而後線程1繼續執行,到這裏,spa

synchronized (lock2) {
	System.out.println(Thread.currentThread().getName()+"獲取了lock2鎖");
}
複製代碼

此時須要獲取到lock2這個鎖,可是lock2如今被線程2持有;同時,線程2也開始執行到:線程

synchronized (lock) {
	System.out.println(Thread.currentThread().getName()+"獲取了lock鎖");
}
複製代碼

此時線程2也在嘗試獲取lock這把鎖,可是lock又被線程1持有了。兩個線程都在等待對方釋放資源,形成了死鎖。OK,完成了。。。
當我準備關機時,發現還在等呢? code

??那爲何呢?? 咱們開看下發生了什麼....

  • 經過jps來看下咱們程序進程
  • 使用jstack -l 【pid】 來看下信息

兩個線程都處於BLOCKED狀態了...,繼續往下看
found 1 deadlock.如咱們所願,死鎖發生了!
相關文章
相關標籤/搜索