Java多线程中static变量的使⽤
线程,是我们项⽬中绕不过的重点领域。提到线程,就常会听到线程安全的术语。那什么是线程安全呢?通俗点说,就是线程访问时不产⽣资源冲突。其实,这是⼀个有点难以定义的概念,不是很容易让⼈⼀听就懂的概念。“⼀个类可以被多个线程安全调⽤就是线程安全
的”《Java编程并发实践》。
来说说静态变量、实例变量、局部变量在多线程下的安全问题吧!
(⼀)静态变量:线程⾮安全
1、静态变量:使⽤static关键字定义的变量。static可以修饰变量和⽅法,也有static静态代码块。被static修饰的成员变量和成员⽅法独⽴于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运⾏时数据区的⽅法区内定到他们。因此,static对象可以在它的任何对象创建之前访问,⽆需引⽤任何对象。
⽤public修饰的static成员变量和成员⽅法本质是全局变量和全局⽅法,当声明它的类的对象时,不⽣成static变量的副本,⽽是类的所有实例共享同⼀个static变量。
2、静态变量使⽤的场景:
(1)对象间共享值时
(2)⽅便访问变量时
3、静态⽅法使⽤注意事项:
(1)不能在静态⽅法内使⽤⾮静态变量,即不能直接访问所属类的实例变量;
(2)不能在静态⽅法内直接调⽤⾮静态⽅法;
(3)静态⽅法中不能使⽤this和super关键字;
4、验证静态变量的线程安全性:
(1)从程序执⾏的图中我们可以看出,执⾏结果中有错误数据,证明了静态变量是存在资源冲突问题的。
static修饰的变量(2)程序运⾏结果图:
5、结论:静态变量也称为类变量,属于类对象所有,位于⽅法区,为所有对象共享,共享⼀份内存,⼀旦值被修改,则其他对象均对修改可见,故线程⾮安全。
(⼆)实例变量:单例时线程⾮安全,⾮单例时线程安全
1、实例变量:实例变量属于类对象的,也就是说,属于对象实例私有,在虚拟机的堆中分配。
2、验证实例变量的线程安全性:
(1)从程序截图中,我们可以看到,当为单例模式时,会产⽣资源冲突,当⾮单例模式时,则不会产⽣线程冲突。
(2)程序运⾏结果图:
图1:
图2:
3、结论:实例变量是实例对象私有的,系统只存在⼀个实例对象,则在多线程环境下,如果值改变后,则其它对象均可见,故线程⾮安全;如果每个线程都在不同的实例对象中执⾏,
则对象与对象间的修改互不影响,故线程安全。
(三)局部变量:线程安全
1、局部变量:定义在⽅法内部的变量。
2、验证局部变量的安全性:
(1)从程序截图中可以看出,局部变量在多线程下没有产⽣资源冲突的问题
(2)程序运⾏结果图:
3、结论:每个线程执⾏时都会把局部变量放在各⾃的帧栈的内存空间中,线程间不共享,故不存在线程安全问题。(四)静态⽅法的线程安全性
1、静态⽅法中如果没有使⽤静态变量,则没有线程安全的问题;
静态⽅法内的变量,每个线程调⽤时,都会新创建⼀份,不会公⽤⼀个存储单元,故不存在线程冲突的问题。
以上就是对多线程环境下静态变量、实例变量和局部变量的⼀点点研究,也仅供⾃⼰在需要或遗忘的时候查询参考下了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论