线程安全粗解
时间:2019-10-08 19:06:09
收藏:0
阅读:80
1、个人理解的java粗略的内存模型
说明如下:
1、在类加载的时候,通过类加载器将.class文件放到方法区,方法区中存放了对象描述的数据结构等信息
2、对象进行实例化后,将实例化的信息放在了堆区,实例化后的引用放在栈区
问题:为什么servlet不是线程安全的?
答:servlet是一个单实例的(在servlet启动服务器的时候,读取了web.xml文件,此时就会将servlet进行加载,并实例化,然后初始化,后续调用servlet时,不再进行实例化,所以是单例的) ,此时在方法区中存在一个servlet的类信息、堆区中存在一个servlet的实例化对象,当访问servlet时,容器会从容器的线程池中拿一个线程出来调用servlet,此时栈区中存在一个servlet的引用。
在并发的情况下,堆区依然只会有一个servlet对象的实例,但是栈区中存在多个对象的引用,如果servlet中存在一个成员变量,那么在修改这个成员变量时,就可能会出现线程的行为结果不正确,这就是servlet线程不安全。
总结:(注:我们在使用spring的时候,controller、service等都是单实例的,如果出现成员变量,会导致线程不安全。)
- 常量始终是线程安全的,因为只存在读操作。
- 每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。
- 局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。
序号 | 是否存在静态变量 | 是否存在成员变量 | 是否单实例 | 是否线程安全 |
1 | 是 | 否 | 是 | 否 |
2 | 否 | 是 | 是 | 否 |
3 | 否 | 否 | 是 | 是 |
4 | 是 | 否 | 否 | 是 |
5 | 否 | 是 | 否 | 是 |
6 | 否 | 否 | 否 | 是 |
上面的描述只是个人理解,如存在问题,请大家指出!
原文:https://www.cnblogs.com/saber-servlet/p/11636740.html
评论(0)