JAVA中關於同步與死鎖的問題


java中當多個現成同時操縱同一資源的時候需要考慮同步的問題。如車站售票,不同售票點賣同一班次車票的時候就要同步,否則賣票會有問題。下面代碼模擬車站賣票:

class TicketSeller implements Runnable
{
    public int ticket = 20;

    public void run()
    {
        for(int i = 0; i < 100; i++)
        {
            synchronized(this)
            {
                if(this.ticket-- >0)
                {
                    Utilities.sleep(300);
                    System.out.println(Thread.currentThread().getName() + "賣出一張票,余票:" + (this.ticket) + "張");
                }
            }
        }
    }
}


class Utilities
{
    public static void sleep(int timeSpan)
    {
        try
        {
            Thread.sleep(timeSpan);
        }
        catch (Exception e)
        {
        }
    }
}

class Hello
{
    public static void main(String[] args) 
    {
        TicketSeller ts = new TicketSeller();
        Thread tl = new Thread(ts,"銅梁站");
        Thread bs = new Thread(ts,"璧山站");
        Thread spb = new Thread(ts,"沙坪壩站");

        tl.start();
        bs.start();
        spb.start();
    }
}

輸出結果:

 

但有時過多的使用同步會造成程序性能下降。除此之外過多同步還會發生更嚴重的后果:死鎖。

也就是說,同步代碼塊中都去爭奪同一資源,互不相讓。舉個例子,在一條東西方向的狹窄的巷道中,AB兩車相遇,互補退讓,結果是兩個車都走不了,這就是死鎖。這里隱含了一個情景就是,A車占有東邊這一段道路,它需要B車讓出B車占有西邊的道路,而同時B車占有西邊的道路,它需要A車讓出A車所占有的西邊的道路。兩車各自占有各自的資源,且同時爭奪對方占有的資源,互補相讓,就造成了死鎖。

這里,為了更好的闡述並模擬JAVA中死鎖的情況。我再舉一個例子:

小紅和小明馬上就要畢業了,都在准備畢業論文的撰寫。他們的論文都要用到兩本書,一本是《匯編語言》,另一本是《算法導論》。他們都要去圖書館借閱這兩本書,但圖書館規定某一人一次只能借閱1本書。於是小紅借了《匯編原理》,小明借了《算法導論》。過了一段時間后,他們論文都完成了一 半。此時,小紅需要小明手中的《算法導論》,同時小明也要小紅手中的《匯編原理》。但是小紅對小明說:“你先把《算法導論》給我了,我完成論文后就把《匯編原理》給你。” 小明不同意,他對小紅說:“你把《匯編原理》先給我,我完成論文后把《算法導論》給你。” 這樣,小紅和小明各持有一本書,卻又要求獲得對方的書才交出自己持有的那本書。他們兩人互不相讓,結果就導致了死鎖的發生。

現在我用JAVA語言對以上場景進行模擬:

class Book
{
    public String name;
    public float price;

    public Book(String name, float price)
    {
        this.name = name;
        this.price = price;
    }
}


class Student implements Runnable
{
    private String studentName;
    private   Book book1;
    private   Book book2;

    public Student(String studentName,Book book1, Book book2)
    {
        this.book1 = book1;
        this.book2 = book2;

        this.studentName = studentName;
    }

    public void run()
    {
        synchronized(this.book1)
        {
            System.out.println(this.studentName+"拿到了"+this.book1.name +"開始寫論文");
            Utilities.sleep(5000);
            System.out.println(this.studentName+"完成一半需要"+this.book2.name);
            synchronized(this.book2)
            {
                System.out.println(this.studentName+"拿到了"+this.book2.name +"繼續寫論文");
            }
            System.out.println(this.studentName+"完成了論文");
        }
        
    }
} 


class Utilities
{
    public static void sleep(int timeSpan)
    {
        try
        {
            Thread.sleep(timeSpan);
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }
}

class Hello
{
    public static void main(String[] args) 
    {
        Book book1 = new Book("匯編原理",23.5f);
        Book book2 = new Book("算法導論",85.5f);

        Thread xh = new Thread(new Student("小紅",book1,book2));
        Thread xm = new Thread(new Student("小明",book2,book1));
        xh.start();
        xm.start();
    }
}

輸出結果:

上圖顯示,程序一直卡在這個地方,不會往下執行。這就是死鎖。


免責聲明!

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



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