亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

java的static靜態變量是不是不安全的?應該如何正確的使用他呢

java的static靜態變量是不是不安全的?應該如何正確的使用他呢

MYYA 2019-02-16 18:11:20
聲明一個static int 變量,在多個線程中對他進行操作,就會出現數據異常的問題, 那么我們在日常情況下應該如何正常,正確的使用static關鍵字呢,是一定要和final關鍵字聯合使用嗎,還是什么樣的變量可以用static聲明什么樣的最好不要 ----------------------------------------------------------------下面是我獲得到的我想要的答案 就是我們平常web開發中,很少會使用主動使用多線程,但是還有一種多線程情況就是每個用戶都是一個線程,當訪問量很大的時候是不是也就是多線程了呢,可是這種時候你使用非靜態成員變量是沒問題的,因為每個用戶都是不同的實例,每個用戶都是new的新的類對象,所以類中的變量也都是互相不干擾的,也就是線程安全的,但如果是靜態變量,就是多用戶共享,也就是多線程共享,所以多個用戶同時修改數據時就會出現問題,難道我們平常開發中每次使用靜態變量都要考慮線程安全問題嗎 — coder94 · 35 分鐘前日常web開發中如果不使用多線程,是不用考慮線程安全的問題的對吧。 但是如果使用了靜態變量,即使不開啟多線程,也要考慮多線程安全問題對嗎,因為每個用戶都是多個線程,都會同時操作靜態變量 — coder94 · 28 分鐘前大哥,你這是另一個問題了,我是針對你剛剛的問題答的。如果要針對你現在的問題,平常不管是用Spring還是Servlet,都是單例的,會在不同請求線程之間共享,所以其不管是實例變量還是靜態變量都會被共享。如果確定要共享,那么需要確保線程安全性。但是如果要在多個請求間共享可變變量呢?根據業務場景不同而不同,可以采用我上述提到的java自帶的機制及加鎖等,也可以采用消息隊列,數據庫,redis. — xbynet · 26 分鐘前還有一點要糾正你一下,不是只有靜態變量才會被共享,一個實例變量被多個線程使用時也是被共享的。 — xbynet · 24 分鐘前回復 coder94:日常web開發,每個http請求一個線程。如果你不涉及共享可變變量,是不需要考慮線程安全性的。如果你想共享一些信息,對于傳統單體應用來說,簡單點可以通過session來共享。 還有點,你關于線程安全的東西,建議你去補補理論基礎。推薦一本經典書:<<Java并發編程實戰>> 國外大牛寫的,不是國內的那本。 — xbynet · 13 分鐘前回復 xbynet:好的 ,謝謝 ,我剛試了下,您說的對,不是靜態變量也會被共享 — coder94 · 12 分鐘前
查看完整描述

2 回答

?
慕森卡

TA貢獻1806條經驗 獲得超8個贊

類中的靜態變量在程序運行期間,其內存空間對所有該類的對象實例而言是共享的,為了節省系統內存開銷、共享資源,應該將一些變量聲明為靜態變量。
代碼一:

public class MemoryTest {

 static class Data{    
     private int week;    
     private String name;    
     Data(int i, String s){    
         week = i;    
         name = s;    
     }    
 }    
     
 Data weeks[] = {    
         new Data(1,"monday"),    
         new Data(2,"Tuesday"),    
         new Data(3,"Wednesday"),    
         new Data(4,"Thursday"),    
         new Data(5,"Friday"),    
         new Data(6,"Saturday"),    
         new Data(7,"Sunday")    
 };    
     
 public static void main(String[] args) {    
     final int N = 20000;    
     MemoryTest test = null;    
     for (int i = 0; i <=N; i++) {    
        test = new MemoryTest();    
     }    
     System.out.println(test.weeks.length);    
 }    

}

代碼二:

public class MemoryTest {

  static class Data{    
      private int week;    
      private String name;    
      Data(int i, String s){    
          week = i;    
          name = s;    
      }    
  }    
     
 static Data weeks[] = {    
         new Data(1,"monday"),    
         new Data(2,"Tuesday"),    
         new Data(3,"Wednesday"),    
         new Data(4,"Thursday"),    
         new Data(5,"Friday"),    
         new Data(6,"Saturday"),    
         new Data(7,"Sunday")    
 };    
     
 public static void main(String[] args) {    
     final int N = 20000;    
     MemoryTest test = null;    
     for (int i = 0; i <=N; i++) {    
         test = new MemoryTest();    
     }    
     System.out.println(test.weeks.length);    
 }    

}

應該發現上面那兩個類的區別吧

Data weeks[] 與 static Data weeks[]

代碼一會在內存中保存20000個weeks的副本,而代碼二則在內存中保存1個weeks的副本,然后共享該副本,這樣的話就不會造成內存的浪費。

雖然靜態的變量能節約大量的內存,但是并不是所有的地方都適合用,建議在下列條件都符合的情況下,盡量用靜態變量:

(1)變量所包含的對象體積較大,占用內存較多。

(2)變量所包含的對象生命周期較長。

(3)變量所包含的對象數據穩定。

(4)該類的對象實例有對該變量所包含的對象的共享需求。

如果變量不具備上述特點,建議不要輕易使用靜態變量。

最后,再提一點內存的優化,就是有關對象的重用,比如:對象池和數據庫連接池等。那樣的話,是很節約內存空間的,不過,在用的時候要考慮各個方面,比如:運行環境的內存資源的限制等。為了防止對象池中的對象過多,要記得清除。

查看完整回答
反對 回復 2019-03-01
  • 2 回答
  • 0 關注
  • 660 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號