java多線程死鎖實例,線程鎖並不可怕


為了測試java多線程死鎖

得到java多線程死鎖的直觀感覺,寫出以下測試代碼。

public class TestDeadLock
{
public static void main(String[] args)
{
   A a=new A();
   B b=new B(a);
   a.set(b);
   Thread t1=new Thread(a);
   Thread t2=new Thread(b);
   t1.start();
   t2.start();
}
}

class A implements Runnable
{
public B b;
public void run()
    {
   while (true)
   {
      synchronized(this)
      {
      b.write();
      }
   }
    }
public void write()
{
    synchronized (this)
    {
       System.out.println("a write");
    }
}
public void set(B b)
    {
   this.b=b;
    }
}
class B implements Runnable
{
public A a;
public B(A a)
    {
     this.a=a;
    }
public void write()
{
    synchronized (this)
    {
       System.out.println("b write");
    }
}
public void run()
    {
   while (true)
   {
      synchronized(this)
      {

      a.write();
      }
   }
    }
}

1、代碼導讀

對象a使用獨立線程去調用對象b的方法。

對象b使用獨立線程去調用對象a的方法。

對象a在調用b的方法之前對自己加鎖,調用對象b后對對象b加鎖。

對象b在調用a的方法之前對自己加鎖,調用對象a后對對象a加鎖。

2、死鎖形成原因解讀

a首先鎖了自己,b鎖了自己,

a去拿b的鎖,發現b已經鎖定了,則等待b的鎖釋放

b去拿a的鎖,發現a已經鎖定,則等待a釋放。

就這樣a等b,b也等a,造成了死鎖的問題。

3、死鎖的必要條件

兩個或兩個以上的線程在活動

某個線程拿到了一個鎖以后,還想去拿第二個鎖,即鎖的嵌套

4、預防死鎖的編程規范和方法。

@1、如果某個對象拿到了自己的鎖,如果想要去拿另外對象的鎖,一定要先釋放自己的鎖。任何鎖嵌套都是不安全的

@2、加鎖的代碼塊,其中盡量不要去調用另外的方法。因為很難在子方法中施放鎖。如果需要調用到其他的方法,需確定該方法以及其子分支肯定不會申請本鎖以外的鎖。

@3、遇到鎖中必須調用其他鎖的情況,必須確定下個鎖對象中不會再回調。所有鎖調用都是拓撲序的。

@4、在生產者--消費者模型中,使用倉庫的概念使得生產者與消費者脫離,即生產者不會需要去拿消費者的鎖,消費者也不會去需要拿生產者的鎖。他們只需要去拿倉庫的鎖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM