怎么建购物网站,网站建设费要摊销吗,wordpress文章采集排版,php自适应网站很多人喜欢在action 或service或dao层继承一些公共的东西 比如jdbc或一些其他的东西 我看过一些小源码也经常这样 废话不多说 直入正题 直入正题前先科普一下TheardLocal类 懂的人直接跳 线程不安全指的是一个带有类成员变量#xff08;状态#xff09;的类的单列被多个线程访…很多人喜欢在action 或service或dao层继承一些公共的东西 比如jdbc或一些其他的东西 我看过一些小源码也经常这样 废话不多说 直入正题 直入正题前先科普一下TheardLocal类 懂的人直接跳 线程不安全指的是一个带有类成员变量状态的类的单列被多个线程访问时才会造成线程不安全TheardLocal简单来说就是一个map (线程ID对象)具体就不多说了需要详细了解的请百度。 TheardLocal的出现解决了这一问题现在很多框架都运用了这个技术将所有的成员变量都放在TheardLocal内这样就不会出现线程安全了这也是为什么Spring jdbcTemplate的事物管理不会存在多线程安全问题。你没发现你所有的注入用的都是这一个单列对象吗还有很多很多地方都是这样的。 现在SpringMvc等使用的是方法及传惨方法体有独自的栈不存在线程安全这样就可以让你的action无论多少个请求都只实列化一次并且不会造成线程安全。 上面这一段只 为告诉你 减少实例对象 使用单列模式 不然下面的没必要看了 因为目的就是为了减少实例对象 正题 四个很简单的java类 [codequot;javaquot;]public class Animal { public Animal(){ System.out.println(1); } } [codequot;javaquot;]public class Dog extends Animal{ } [codequot;javaquot;]public class Pig extends Animal{ } [codequot;javaquot;]public class Test { public static void main(String[] args) { new Dog(); new Pig(); } } 输出的肯定是两个1 这能证明什么呢 Animal 被实例化了两次 如果你的项目中action多达100个 甚至1000个 那么这个类被实例化的次数会随着你的action数量变得越来越多如果你使用的是单列还好如果是多列那这个次数就等于 请求数*子类 请使用注入的方式因为它只是一个对象的引用10000个引用它在内存中还是那么大。 不要为了那么两行代码的方便性影响了性能 使用继承前先想好它可能会有多少个子类太多了就用注入也就多两行代码。 楼主目前做的两个项目中业务层都没有用过继承虽然几乎每个类都用了jdbc但是都是注入进来的。 实践验证真理 额 我承认我错了 不过也学到很多东西 感谢大家的打击 下面是我的实践 第一段 public class Animal { public void getInfo(){ //一大堆代码 } //还可以加N多方法运行结果也一致 } public class Dog extends Animal{ } public class Pig { public Animal animal; } 第一种运行方式 继承 public static void main(String[] args) { Long begin new Date().getTime(); ListDog l new ArrayListDog(); for (int i 0; i 1000000; i) { Dog d new Dog(); l.add(d);//添加到一个集合里避免无引用被垃圾回收 } Long runTime new Date().getTime()-begin; System.out.println(runTime); } 第二种运行方式 注入 public static void main(String[] args) { Long begin new Date().getTime(); ListPig l new ArrayListPig(); Animal animal new Animal(); for (int i 0; i 1000000; i) { Pig d new Pig(); d.animal animal; l.add(d);//添加到一个集合里避免无引用被垃圾回收 } Long runTime new Date().getTime()-begin; System.out.println(runTime); } 两个运行结果占用内存一致时间几乎一致 证明一个非静态方法在内存中只会占一个地址 与静态的区别在于静态是系统启动时分配 非静态是第一次实例时分配 无论后续实例多少次它只会占用一个内存地址 所以测试时应该独立启动运行 不然第二步骤实例Animal类时其实一点时间也没花内存也没变 第二段 将Animal类添加一个非静态成员变量 public Integer age new Integer(10); 两个运行结果 第二种运行时间内存占用比第一种小一倍 证明一个类在实例化的时候会为成员变量分配内存空间 而方法不会 第三段 将Animal类添加一个方法引用age 与第二段一致 证明方法在使用成员变量时只是引用不是复制 第四段 将Animal类添加一个构造函数 public Animal(){ //打印 } 注入的方式构造函数运行一次 继承的方式随子类实例次数 最后总结 1一个类在实例化时 非静态并且有值的成员变量int long String这些类型在不使用构造传参时 如果参数一致在内存中也会存在一个会在分配在内存中 以后每次实例也都会 非静态方法只会在第一次实例化时分配 以后每次的实例都只是引用 2父类在很多子类继承时构造函数不要过于复杂因为构造函数在每次实例化时都会运行一次 3一个类如果构造函数是空并且也没有非静态不为空的成员变量那么 new 一个类一百次 和new一个类一次 加100此空循环 无论内存占用还是速度都一致 转载于:https://www.cnblogs.com/shhaoran/archive/2013/02/04/2924524.html