1. 程式人生 > 其它 >多執行緒中使用靜態方法存線上程安全的問題

多執行緒中使用靜態方法存線上程安全的問題

類的成員分兩類,靜態成員(static member)和例項成員(instance menber),靜態成員屬於類,例項成員則屬於物件,即類的例項。
我們知道,靜態欄位和靜態方法的呼叫都是通過類來呼叫的,靜態方法不會對特定的例項操作,只能呼叫呼叫類中的其他屬性和靜態方法,不能呼叫類中的非靜態屬性和非靜態方法。例項方法可以對特定的例項操作,既能訪問靜態屬性和靜態方法,也能訪問例項屬性和例項方法。
在多執行緒中使用靜態方法是否有安全問題?這樣看在靜態方法中時候使用了靜態成員。在多執行緒中使用一個靜態方法的時候,每個執行緒共享一個靜態欄位,如果該靜態方法不去操作一個靜態變數,只在方法內部使用區域性變數,則不會造成安全性問題。但是,如果該靜態方法操作了一個靜態欄位,則需要在靜態方法中採用互斥訪問的方式來對其進行安全處理。

先來看沒有執行緒安全問題的例項

 public class Test
 {
    public static String hello(String str)
    {
        String tmp = "";
        tmp = tmp + str;
        return tmp;
    }
 }

  上述示例中是執行緒安全的,這是因為在靜態方法中聲明瞭區域性變數,每個執行緒在呼叫的時候,都會建立一份新的區域性變數,比如這裡的tmp,而不會共享一個儲存單元。

   以下是執行緒不安全的:

   public class Test
 {
   Private static Test test
    public static Test hello()
{
If(tets==null)
  Test=new Test();        
return test;
    }
 }

  

這是因為在靜態方法中又返回了靜態變數,對於靜態變數來說,類在載入的時候會佔用同一個儲存區,而每個執行緒都是公用這個儲存區的,因此存線上程安全的問題。
因此在設計工具類的時候,對於沒有使用到靜態變數的靜態工具類方法,是不需要加鎖的(synchronized)。
在使用單例模式做工具類的時候,這個時候靜態方法需要被加鎖,這是因為所有的執行緒雖然有自己的方法棧,但是在方法棧中操作的是同一個物件的實體,所以需要進行加鎖同步,來實現每個執行緒都需要等待鎖的釋放才能使用該物件的引用。
但是在多例模式做工具類的時候,是不需要加鎖的,因為每個執行緒中有自己的方法棧,但是在方法棧中建立了獨立的物件引用,可以看成是執行緒都是在自己的方法棧中操作區域性的物件引用,因此這個時候不需要同步。
————————————————
版權宣告:本文為CSDN博主「_花開滿樓」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/qq_28269905/article/details/72123572