聲明一個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)該類的對象實例有對該變量所包含的對象的共享需求。
如果變量不具備上述特點,建議不要輕易使用靜態變量。
最后,再提一點內存的優化,就是有關對象的重用,比如:對象池和數據庫連接池等。那樣的話,是很節約內存空間的,不過,在用的時候要考慮各個方面,比如:運行環境的內存資源的限制等。為了防止對象池中的對象過多,要記得清除。
添加回答
舉報
0/150
提交
取消