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