今天晚上收获颇丰
详细讨论了java的一些知识
引入点是 单例多线程 多例单线程
单例多线程: SpringMVC 的设计
多例单线程: Struts2 的设计
单例多线程
是指 Spring在启动的时候 为 @Controller 注解到的Controller进行对象的创建 而且仅创建这么一份 当有大量用户访问该Controller内的方法的时候 会产生相应数量或者达不到最大值Thread的线程 进行方法的执行 不会再创建Controller对象了 只用当前这个被Spring创建好的对象即可
多例单线程
是指 在Struts2 使用的时候 每来到一个用户的请求 就会为该用户请求上下文创建一个对应的Action对象 每个Action对象里面都会有一个值栈对象(只有一个)
因此在用户量大的时候 Struts2 的模式就会创建大量的对象 对内存的压力比较大 不推荐使用
接着就谈到了 栈 堆 的问题
贴上好的帖子:
https://blog.csdn.net/ns_code/article/details/17565503
比较重要的一点
方法区是线程共享的 堆也是线程共享的 栈是线程私有的
理解:
共享是相对于私有来讲的
私有--每个线程会对应一块私有的栈区 每个栈区会对应其内部的栈帧 每个栈帧就是对应的方法
共享--JVM启动后会且只会产生一个 堆区 所有线程的产生的对象等属于堆的元素都放在这一个大的区域里面 所以叫共享
而不是我们理解的 线程之间共享
全局变量(在java中可以理解为用static final修饰):
在java中全局变量也称成员变量,是创建对象的时候分配内存的。全局常量存于全局数据区。
具体的概念:
JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
线程的安全与不安全
造成线程不安全的原因不是多个线程同时执行同一块代码
因为每个线程都会产生自己私有的 栈区 每个方法又座位栈帧出现在栈区内部 所以不会造成线程之间数据串掉
真正原因是 访问 全局变量 与 静态变量
原因:
全局变量
存在于堆中 因为堆是共享的 不同线程都从这个大区域内拿值
当类对象创建之后 会在堆里面创建该全局变量的对象 得到引用
在使用该全局变量的时候 所有的线程都是使用的这一个 会造成数据混乱 从而造成线程不安全
静态变量
存在于方法区中 因为方法区也是共享的 不同线程都是从这个大区域内拿值
所以会造成数据混乱 从而造成线程的不安全
网友评论