多線程死鎖


在多線程中如何找到安全問題所在:
1,明確哪些代碼是多線程運行代碼
2,明確共享數據
3,明確多線程運行代碼中哪些代碼是操作共享數據的


靜態的同步方法中,使用鎖是該方法所在類的字節碼文件對象,即 類名.class 

 

 

前天俺們談到了加鎖,但是在使用加鎖的同時又會帶來一個問題,就是死鎖。什么叫死鎖?

所謂死鎖: 是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。   

那么為什么會產生死鎖呢?

1.因為系統資源不足。

2.進程運行推進的順序不合適。   

 3.資源分配不當。            

 學過操作系統的朋友都知道:產生死鎖的條件有四個:

1.互斥條件:所謂互斥就是進程在某一時間內獨占資源。

2.請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

3.不剝奪條件:進程已獲得資源,在末使用完之前,不能強行剝奪。

4.循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。

  

例如:     

死鎖是因為多線程訪問共享資源,由於訪問的順序不當所造成的,通常是一個線程鎖定了一個資源A,而又想去鎖定資源B;在另一個線程中,鎖定了資源B,而又想去鎖定資源A以完成自身的操作,兩個線程都想得到對方的資源,而不願釋放自己的資源,造成兩個線程都在等待,而無法執行的情況。

分析死鎖產生的原因不難看出是由訪問共享資源順序不當所造成的,下面寫一個造成線程死鎖的例子,希望能對大家理解多線程死鎖問題有進一步的理解!如果有人需要編寫多線程的系統,當操作共享資源時一定要特別的小心,以防出現死鎖的情況!

package com.oyqh;  
  
public class RunnableTest implements Runnable {  
    private int flag = 1;  
    private static Object obj1 = new Object(), obj2 = new Object();  
  
    public void run() {  
        System.out.println("flag=" + flag);  
        if (flag == 1) {  
            synchronized (obj1) {  
                System.out.println("我已經鎖定obj1,休息0.5秒后鎖定obj2去!");  
                try {  
                    Thread.sleep(500);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                synchronized (obj2) {  
                    System.out.println("1");  
                }  
            }  
        }  
        if (flag == 0) {  
            synchronized (obj2) {  
                System.out.println("我已經鎖定obj2,休息0.5秒后鎖定obj1去!");  
                try {  
                    Thread.sleep(500);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                synchronized (obj1) {  
                    System.out.println("0");  
                }  
            }  
        }  
    }  
  
    public static void main(String[] args) {  
        RunnableTest run01 = new RunnableTest();  
        RunnableTest run02 = new RunnableTest();  
        run01.flag = 1;  
        run02.flag = 0;  
        Thread thread01 = new Thread(run01);  
        Thread thread02 = new Thread(run02);  
        System.out.println("線程開始嘍!");  
        thread01.start();  
        thread02.start();  
    }  
}  
<span style="font-size:18px;">package com.oyqh;  
  
public class RunnableTest implements Runnable {  
    private int flag = 1;  
    private Object obj1 = new Object(), obj2 = new Object();  
  
    public void run() {  
        System.out.println("flag=" + flag);  
        if (flag == 1) {  
            synchronized (obj1) {  
                System.out.println("我已經鎖定obj1,休息0.5秒后鎖定obj2去!");  
                try {  
                    Thread.sleep(500);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                synchronized (obj2) {  
                    System.out.println("1");  
                }  
            }  
        }  
        if (flag == 0) {  
            synchronized (obj2) {  
                System.out.println("我已經鎖定obj2,休息0.5秒后鎖定obj1去!");  
                try {  
                    Thread.sleep(500);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                synchronized (obj1) {  
                    System.out.println("0");  
                }  
            }  
        }  
    }  
  
    public static void main(String[] args) {  
        RunnableTest run01 = new RunnableTest();  
        RunnableTest run02 = new RunnableTest();  
        run01.flag = 1;  
        run02.flag = 0;  
        Thread thread01 = new Thread(run01);  
        Thread thread02 = new Thread(run02);  
        System.out.println("線程開始嘍!");  
        thread01.start();  
        thread02.start();  
    }  
}</span>  

 這樣就產生了死鎖,這是我們過多的使用同步而產生的。我們在Java中使用synchonized的時候要考慮這個問題,如何解決死鎖,大家可以從死鎖的四個條件去解決,只要破壞了一個必要條件,那么我們的死鎖就解決了。在java中使用多線程的時候一定要考慮是否有死鎖的問題.

The other example:

one:

<span style="font-size:18px;">class Ticket implements Runnable  
{  
    private int tick=100;  
    Object obj=new Object();  
    boolean flag=true;  
    public void run(){  
        if (flag)  
        {  
            while (true)  
            {  
                synchronized(obj){  
                    show();  
                }  
            }  
        }  
        else   
            while (true)  
                show();  
    }  
    public synchronized void show(){  
        synchronized(obj){  
                if (tick>0)  
                {  
                    try{Thread.sleep(10);}catch(Exception e){}  
                    System.out.println(Thread.currentThread().getName()+"...code..."+tick--);  
                }  
        }  
    }  
}  
class DeadLockDemo  
{  
    public static void main(String[] args){  
        Ticket t=new Ticket();  
        Thread t1=new Thread(t);  
        Thread t2=new Thread(t);  
        t1.start();  
        try{Thread.sleep(10);} catch(Exception e){}  
        t.flag=false;  
        t2.start();  
    }  
}</span>  
[java] view plain copy
<span style="font-size:18px;"></span>   
[java] view plain copy
<span style="font-size:18px;">two:</span>  
[java] view plain copy
<span style="font-size:18px;">class TestDeadLock  
{  
    private boolean flag;  
    TestDeadLock(boolean flag){  
        this.flag=flag;  
    }  
    public void run(){  
        if (flag)  
        {  
                synchronized(MyLock.locka){  
                    System.out.println("if's locka");  
                    synchronized(MyLock.lockb){  
                        System.out.println("if's lockb");  
                    }  
                }  
        }  
        else{  
            synchronized(MyLock.lockb){  
                System.out.println("else's lockb");  
                synchronized(MyLock.locka){  
                    System.out.println("else's locka");  
                }  
            }  
        }  
    }  
}  
  
  
class MyLock  
{  
    static Object locka=new Object();  
    static Object lockb=new Object();  
  
}  
  
class DeadLockTest  
{  
    public static  void main(String[] args){  
        Thread t1=new Thread(new TestDeadLock(true));  
        Thread t2=new Thread(new TestDeadLock(false));  
        t1.start();  
        t2.start();  
    }  
}</span>  
[java] view plain copy
<span style="font-size:18px;"></span>   

 


免責聲明!

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



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