Java线程安全隐患

最近一直在考虑java线程安全的问题,在java的语言体系里面,究竟哪些地方存在线程安全的隐患呢?以下是笔者的一点愚见,欢迎广大网友拍砖!

众所周知:类由两部分组成,方法和变量,我们先说说这个对象的方法:

最有可能引起线程安全问题的当属单例对象的公有方法和类的公有静态方法。据我所知,方法是加载在栈里面执行的,而对于多线程来说,每个线程有它自己的栈,所以我据此推断,单例对象的方法 或者 类的公有静态方法,应该是加载在每个线程自己的栈里面去独立执行的。如果我的推断是正确的,那么不管什么类型的方法,如果不考虑它用的变量,仅仅就方法本身而言,都是线程安全的。

接下来,我们说说变量,变量又分类变量,实例变量,局部变量。

A. 类变量如果是引用的引用类型对象的话,因为是存储在堆里面,是所有线程栈所共享的,所以存在线程安全的隐患,因此程序员要特别当心。

B. 实例变量又可以分为多例对象的实例变量和单例对象的实例变量,如果是引用的引用类型对象的话,它也是存储在堆里面的,是所有线程栈所共享的,但是多例对象的实例变量不存在线程安全问题(这个为什么就不用我解释了吧!),而单例对象的实例变量存在线程不安全的风险,这个大家也要当心!例如最经典的:Servlet对象、以及Struts1里面的Action对象的实例变量就是线程不安全的!

C. 局部变量是方法内部实例化的变量,方法执行完后就被垃圾回收了。局部变量如果是基本类型,是放在线程栈里面的,每个线程无法共享,因此不存在线程安全的问题;如果是对象类型,在Stack里保存地址,在Heap里保存值,只要不去引用外部的单例对象,也不会存在线程安全的问题。换句话说,如果在方法体内部new了一个HashMap,即便HashMap本身是线程不安全的,但是在这种情况下,依然是线程安全的。

你可能感兴趣的:(java,多线程,线程安全,stack,heap)