java static方法的線程安全性

本文轉載自:http://xuchenguang.blog.51cto.com/730272/422939

本人曰:剛學java、jsp不久,對static變量倒是有所理解,但是,對static方法理解不夠清楚,看完這篇文章,覺得還是講的蠻清晰的,所以轉載來備忘,也和大家一起分享學習之。
~~~~~~~~~~~~~以下轉載~~~~~~~~~~~~~~~~~~~~~~~~~~~
最近幾年用Java寫了一些多線程的程序,有一種需求,是建立一個公用的static類型Llit,類裏面寫了一些對於List的get、set、 update之類的方法,而有一個線程從數據庫中讀取數據並維護這個List,其它有幾百個幾千個線程讀取和修改這個List。
       寫本文的目的,就是爲這種需求提出最佳解決方案:
        一、首先了解一下同步安全問題:
對於線程安全,我們先看兩個例子:
class CheckoutLane
{
    public static float GetTotal(Cart cart)
    {
        float total = 0;

        for (int i = 0; i < cart.GroceryItems.Length; i++)
        {
            total += cart.GroceryItems[i].Price; 
            Thread.Sleep(100);
        }
        return total;
    }
}

對於上面的代碼,你使用多少的線程來控制,都是安全的。因爲線程之間,不會共享什麼資源,唯一相同的是使用了同一個邏輯。其實這是在破壞線程的前題方面下功夫,出現線程不安全的條件都沒有了,那肯定就是線程安全的。

class CheckoutLane
{
    static float total;
    public static float GetTotal(Cart cart)
    {
        total = 0;
        for (int i = 0; i < cart.GroceryItems.Length; i++)
        {
            total += cart.GroceryItems[i].Price;  
            Thread.Sleep(100);
        }
        return total;
    }
}

對於上面的這個例子,不是線程安全的,因爲共享了static float total;這個資源,而各個線程都隨機都被調用,可以任意修改total這個數據。這個,就正如多個收銀員共享櫃檯,任意執行收銀操作一樣。
二、最簡單的解決辦法,加synchronized:
        在加synchronized之前,首先要明白:
        1、synchronized會影響代碼執行效率;
        2、synchronized雖然加在一個方法上,但是影響的是整個類或類的實例;
        3、兩個synchronized方法不能相互調用,否則會形成死鎖,很好理解,A調B,B調A,A和B相互等着對方結束,但是使用了synchronized,都不能結束,程序就死在那裏了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章