为了账号安全,请及时绑定邮箱和手机立即绑定

java的static静态变量是不是不安全的?应该如何正确的使用他呢

java的static静态变量是不是不安全的?应该如何正确的使用他呢

ABOUTYOU 2019-05-23 19:44:47
声明一个staticint变量,在多个线程中对他进行操作,就会出现数据异常的问题,那么我们在日常情况下应该如何正常,正确的使用static关键字呢,是一定要和final关键字联合使用吗,还是什么样的变量可以用static声明什么样的最好不要----------------------------------------------------------------下面是我获得到的我想要的答案就是我们平常web开发中,很少会使用主动使用多线程,但是还有一种多线程情况就是每个用户都是一个线程,当访问量很大的时候是不是也就是多线程了呢,可是这种时候你使用非静态成员变量是没问题的,因为每个用户都是不同的实例,每个用户都是new的新的类对象,所以类中的变量也都是互相不干扰的,也就是线程安全的,但如果是静态变量,就是多用户共享,也就是多线程共享,所以多个用户同时修改数据时就会出现问题,难道我们平常开发中每次使用静态变量都要考虑线程安全问题吗—coder94·35分钟前日常web开发中如果不使用多线程,是不用考虑线程安全的问题的对吧。但是如果使用了静态变量,即使不开启多线程,也要考虑多线程安全问题对吗,因为每个用户都是多个线程,都会同时操作静态变量—coder94·28分钟前大哥,你这是另一个问题了,我是针对你刚刚的问题答的。如果要针对你现在的问题,平常不管是用Spring还是Servlet,都是单例的,会在不同请求线程之间共享,所以其不管是实例变量还是静态变量都会被共享。如果确定要共享,那么需要确保线程安全性。但是如果要在多个请求间共享可变变量呢?根据业务场景不同而不同,可以采用我上述提到的java自带的机制及加锁等,也可以采用消息队列,数据库,redis.—xbynet·26分钟前还有一点要纠正你一下,不是只有静态变量才会被共享,一个实例变量被多个线程使用时也是被共享的。—xbynet·24分钟前回复coder94:日常web开发,每个http请求一个线程。如果你不涉及共享可变变量,是不需要考虑线程安全性的。如果你想共享一些信息,对于传统单体应用来说,简单点可以通过session来共享。还有点,你关于线程安全的东西,建议你去补补理论基础。推荐一本经典书:国外大牛写的,不是国内的那本。—xbynet·13分钟前回复xbynet:好的,谢谢,我刚试了下,您说的对,不是静态变量也会被共享—coder94·12分钟前
查看完整描述

3 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

类中的静态变量在程序运行期间,其内存空间对所有该类的对象实例而言是共享的,为了节省系统内存开销、共享资源,应该将一些变量声明为静态变量。代码一:
publicclassMemoryTest{
staticclassData{
privateintweek;
privateStringname;
Data(inti,Strings){
week=i;
name=s;
}
}
Dataweeks[]={
newData(1,"monday"),
newData(2,"Tuesday"),
newData(3,"Wednesday"),
newData(4,"Thursday"),
newData(5,"Friday"),
newData(6,"Saturday"),
newData(7,"Sunday")
};
publicstaticvoidmain(String[]args){
finalintN=20000;
MemoryTesttest=null;
for(inti=0;i<=N;i++){
test=newMemoryTest();
}
System.out.println(test.weeks.length);
}
}
代码二:
publicclassMemoryTest{
staticclassData{
privateintweek;
privateStringname;
Data(inti,Strings){
week=i;
name=s;
}
}
staticDataweeks[]={
newData(1,"monday"),
newData(2,"Tuesday"),
newData(3,"Wednesday"),
newData(4,"Thursday"),
newData(5,"Friday"),
newData(6,"Saturday"),
newData(7,"Sunday")
};
publicstaticvoidmain(String[]args){
finalintN=20000;
MemoryTesttest=null;
for(inti=0;i<=N;i++){
test=newMemoryTest();
}
System.out.println(test.weeks.length);
}
}
应该发现上面那两个类的区别吧
Dataweeks[]与staticDataweeks[]
代码一会在内存中保存20000个weeks的副本,而代码二则在内存中保存1个weeks的副本,然后共享该副本,这样的话就不会造成内存的浪费。
虽然静态的变量能节约大量的内存,但是并不是所有的地方都适合用,建议在下列条件都符合的情况下,尽量用静态变量:
(1)变量所包含的对象体积较大,占用内存较多。
(2)变量所包含的对象生命周期较长。
(3)变量所包含的对象数据稳定。
(4)该类的对象实例有对该变量所包含的对象的共享需求。
如果变量不具备上述特点,建议不要轻易使用静态变量。
最后,再提一点内存的优化,就是有关对象的重用,比如:对象池和数据库连接池等。那样的话,是很节约内存空间的,不过,在用的时候要考虑各个方面,比如:运行环境的内存资源的限制等。为了防止对象池中的对象过多,要记得清除。
                            
查看完整回答
反对 回复 2019-05-23
  • 3 回答
  • 0 关注
  • 1868 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信