当前位置: 首页 > news >正文

去哪找人做网站网站网警备案流程

去哪找人做网站,网站网警备案流程,个人网站设计的参考文献,软件项目管理制度单例模式是⼀个单例类在任何情况下都只存在⼀个实例#xff0c;构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例#xff0c;对外提供⼀个静态公有⽅法获取实例。 目录 一、单例模式 饿汉式 静态内部类 懒汉式 反射可以破坏单例 道高一尺魔高一丈 枚举 一、单例…单例模式是⼀个单例类在任何情况下都只存在⼀个实例构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例对外提供⼀个静态公有⽅法获取实例。 目录 一、单例模式 饿汉式 静态内部类 懒汉式 反射可以破坏单例 道高一尺魔高一丈 枚举 一、单例模式 饿汉式 类⼀加载就创建对象这种⽅式⽐较常用但容易产⽣垃圾对象浪费内存空间。 // 饿汉式 public class HungryMan {private HungryMan(){}private final static HungryMan HUNGRY new HungryMan();public static HungryMan getInstance(){return HUNGRY;} } 那么它是如何保证线程安全的呢它是基于类加载机制避免了多线程的同步问题但是如果类被不同的类加载器加载就会创建不同的实例。  优点线程安全没有加锁执⾏效率较⾼。 缺点不是懒加载类加载时就初始化浪费内存空间。 静态内部类 使用静态内部类来实现单例模式是一种非常优雅且线程安全的方式。 这种方法利用了Java类加载机制的特性即静态内部类只有在被引用时才会被加载和初始化从而实现了延迟加载的效果。同时由于Java虚拟机在类加载的过程中是单线程的所以静态内部类初始化过程中的线程安全性得到了保证。 // 静态内部类 public class Holder {private Holder(){}public static class Inner{private static final Holder HOLDER new Holder();}public static Holder getInstance(){return Inner.HOLDER;} } 在这个例子中Holder 类是我们要实现单例的类。我们将其构造函数私有化以防止外部代码直接通过 new Holder () 来创建实例。然后我们创建了一个私有的静态内部类 Inner 它包含一个静态的 Holder 实例。外部代码无法直接访问这个内部类但是可以通过调用 Holder .getInstance() 方法来获取单例实例。 当 Holder .getInstance() 方法被调用时Inner 类会被加载和初始化如果尚未加载的话这个过程是由Java虚拟机在单线程环境中完成的因此是线程安全的。在 Inner 类被初始化的过程中静态变量 INSTANCE 会被创建并且只会被创建一次。因此Holder .getInstance() 方法总是返回同一个 Holder 实例从而实现了单例模式。 懒汉式 懒汉式是一种单例模式的实现方式。这种方式的核心思想是延迟加载也就是在真正需要使用到实例对象时才进行创建而不是在程序启动时就创建。这种方式可以节省系统资源提高程序的运行效率。 在懒汉式单例模式中会将对象的创建过程放到一个静态方法中并在这个方法中进行同步控制以保证在多线程环境下仍然只创建一个实例。当程序第一次调用该方法时会检查实例是否已经创建如果没有则进行创建如果已经创建则直接返回已经创建的实例。 // 懒汉式 public class LayMan {private LayMan(){}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) {for (int i 0; i 10; i) {new Thread(()-{LayMan.getInstance();}).start();}} }那么它是如何保证线程安全呢通过 synchronized 关键字加锁保证线程安全 synchronized 可以添加在⽅法上⾯也可以添加在代码块上⾯存在的问题是每⼀次调⽤ getInstance 获取实例时都需要加锁和释放锁这样是⾮常影响性能的。 在单线程下使⽤没有问题但是 对于多线程是⽆法保证单例的 懒汉式单例模式的主要优点是它的延迟加载特性可以在系统启动时减少不必要的资源消耗。然而由于需要进行同步控制懒汉式单例模式在多线程环境下的性能可能会受到一定影响。此外如果实现不当懒汉式单例模式也可能会存在线程安全问题。 ---》优点懒加载缺点线程不安全 但是还是不安全可以通过反射来破坏单例。 反射可以破坏单例 反射破坏单例模式的方式主要是通过访问并调用类的私有构造函数来创建新的实例。在单例模式中通常会将构造函数设为私有以防止外部代码创建类的多个实例。然而使用Java反射API可以绕过这些访问限制。 具体来说反射破坏单例模式的步骤如下 获取单例类的Class对象。这可以通过调用Class.forName()方法或使用.class语法来完成。 使用Class对象的getDeclaredConstructor()方法来获取私有构造函数的Constructor对象。这个方法可以访问类中的所有构造函数无论它们是公有还是私有。 调用Constructor.setAccessible(true)方法来允许访问私有构造函数。这将取消Java语言的访问检查使得即使构造函数是私有的也可以被调用。 最后使用Constructor.newInstance()方法来创建单例类的新实例。 这样即使单例类的构造函数是私有的也可以通过反射来创建多个实例从而破坏单例模式的约束。 1 import java.lang.reflect.Constructor;// 懒汉式 public class LayMan {private LayMan(){}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) throws Exception {LayMan instance1 LayMan.getInstance();ConstructorLayMan declaredConstructor LayMan.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);LayMan instance2 declaredConstructor.newInstance();System.out.println(instance1);System.out.println(instance2);} } 从代码运行结果可以看的拿到了两个不同的实例  2 import java.lang.reflect.Constructor;// 懒汉式 public class LayMan {private LayMan(){}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) throws Exception {ConstructorLayMan declaredConstructor LayMan.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);LayMan instance2 declaredConstructor.newInstance();LayMan instance3 declaredConstructor.newInstance();System.out.println(instance3);System.out.println(instance2);} } 从代码运行结果可以看的拿到了两个不同的实例   道高一尺魔高一丈 1为了防止反射破坏单例模式可以采取一些防御措施。例如在构造函数中添加检查如果已经存在实例则抛出异常。 import java.lang.reflect.Constructor;// 懒汉式 public class LayMan {private LayMan(){synchronized (LayMan.class){if(layMan ! null){throw new RuntimeException(不用试图使用反射破坏单例);}}}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) throws Exception {LayMan instance1 LayMan.getInstance();ConstructorLayMan declaredConstructor LayMan.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);LayMan instance2 declaredConstructor.newInstance();System.out.println(instance1);System.out.println(instance2);} } 2但是简单的在构造方法里判断layMan是否是null如果是通过反射创建的2个实例就可以通过反射进行破坏了。 import java.lang.reflect.Constructor;// 懒汉式 public class LayMan {private LayMan(){synchronized (LayMan.class){if(layMan ! null){throw new RuntimeException(不用试图使用反射破坏单例);}}}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) throws Exception {ConstructorLayMan declaredConstructor LayMan.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);LayMan instance2 declaredConstructor.newInstance();LayMan instance3 declaredConstructor.newInstance();System.out.println(instance3);System.out.println(instance2);} }从代码运行结果可以看的拿到了两个不同的实例   3红绿灯方法设置一个标志位flag 但是简单的在构造方法里判断l标志位flag是否被修改过也可以通过反射进行破坏。 import java.lang.reflect.Constructor;// 懒汉式 public class LayMan {private static boolean flag false;private LayMan(){synchronized (LayMan.class){if(flag false){flag true;} else {throw new RuntimeException(不用试图使用反射破坏单例);}}}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) throws Exception { // LayMan instance1 LayMan.getInstance();ConstructorLayMan declaredConstructor LayMan.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);LayMan instance2 declaredConstructor.newInstance();LayMan instance3 declaredConstructor.newInstance();System.out.println(instance3);System.out.println(instance2);} }4相应的我们也可以通过反射对这个标志位flag进行修改。 import java.lang.reflect.Constructor; import java.lang.reflect.Field;// 懒汉式 public class LayMan {private static boolean flag false;private LayMan(){synchronized (LayMan.class){if(flag false){flag true;} else {throw new RuntimeException(不用试图使用反射破坏单例);}}}private static volatile LayMan layMan;// 双层检测锁模式public static LayMan getInstance(){if(layMan null){synchronized (LayMan.class){if(layMan null){layMan new LayMan(); // 不是一个原子性操作分配内存空间、执行构造方法初始化对象、把这个对象执行空间}}}return layMan;}public static void main(String[] args) throws Exception { // LayMan instance1 LayMan.getInstance();Field f LayMan.class.getDeclaredField(flag);f.setAccessible(true);ConstructorLayMan declaredConstructor LayMan.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);LayMan instance2 declaredConstructor.newInstance();f.set(instance2, false);LayMan instance3 declaredConstructor.newInstance();System.out.println(instance3);System.out.println(instance2);} } 从代码运行结果可以看的拿到了两个不同的实例   枚举 另外还可以通过枚举类来实现单例因为枚举类在Java中是天然的单例且能够抵御反射攻击。 import java.lang.reflect.Constructor;public enum EnumSingle {INSTANCE;public EnumSingle getInstance(){return INSTANCE;} }class Test{public static void main(String[] args) {EnumSingle instance1 EnumSingle.INSTANCE;EnumSingle instance2 EnumSingle.INSTANCE;System.out.println(instance1);System.out.println(instance2);ConstructorEnumSingle declaredConstructor EnumSingle.class.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);EnumSingle instance3 declaredConstructor.newInstance();System.out.println(instance3);} } 从代码运行结果可以看的拿到了两个不同的实例   并且也可以看到枚举类里是没有一个无参构造方法的。 在Java中枚举类保证单例的方式是通过Java语言规范和Java虚拟机JVM的内部机制来实现的。具体来说有以下几点保证了枚举类的单例特性 语言级别的保障Java枚举类型在设计时就被定义为单例的。Java语言规范中明确指出枚举常量在Java中是由静态final字段表示的它们在第一次被使用时初始化并且由于它们是静态的因此只会被初始化一次。 线程安全枚举常量的加载和初始化是由JVM在类加载的过程中完成的这个过程是线程安全的。由于Java虚拟机提供了类加载机制的安全性因此不需要额外的同步措施来确保枚举常量的线程安全初始化。 反射的限制即使使用Java反射API也无法创建枚举的额外实例。尝试通过反射来调用枚举的构造函数会抛出异常因为JVM不允许这样做。 序列化的安全性枚举类默认实现了Serializable接口并且在序列化时有着特殊的处理。即使枚举实例被序列化后再反序列化也不会创建新的实例而是返回已经存在的枚举常量。 单一实例的保证由于枚举类型的特性每个枚举常量在JVM中只有一个实例不可能通过任何方式创建出第二个相同的实例。 因此使用枚举实现单例模式是一种非常可靠的方法它自动处理了多线程环境下的同步问题并且防止了反射和序列化可能导致的单例破坏。
http://www.hkea.cn/news/14476373/

相关文章:

  • 做明星简介网站侵权吗正规的网站制作电话
  • 固始做网站的公司优化网站标题
  • 寿县有做网站开发的吗手机网站建设规划图
  • 企业网站销售省级建设主管部门网站
  • 网站基本配置优秀网站h5案例分享
  • 福州网站怎么做seo网站浮动窗口怎么做
  • 搜集10个优秀网站学校网站建设机构
  • wordpress访问网站很慢做知乎网站要多少钱
  • 网站美工切图是如何做的dede网站模板怎么安装
  • 宝山做网站wordpress文章打开慢
  • 类似饿了么的网站怎么做交互设计流程
  • 做电气的什么招聘网站好做设备出口网站
  • 做商城网站服务器建设银行官网网站首页
  • 新手学做免费网站软件wordpress 发不出邮件
  • 医院网站建设的目标网站域名不变网站可以从做吗
  • 请描述网站开发的一般流程seo营销推广费用
  • 威海网站建设短信精准群发网站后面的官网是如何做的
  • 有没有专门帮人做图的网站wordpress放视频教程
  • 阿里巴巴外贸网站登录天元建设集团有限公司新闻
  • 成都制作网站软件做外贸的收入一般多少
  • 企业网站制作与维护建设银行e路护航官方网站登陆
  • 自媒体平台企业网站怎么设置高端营销网站建设
  • wordpress设置网站地图电子商务平台
  • 外贸企业官网建站东台专业做网站
  • 广州网站建设 广州亦客网络wordpress 小视频模板
  • 软件论坛网站有哪些网站开发工具简述
  • 网站建设松江景县做网站
  • 网站图标代码wordpress自动水印代码
  • 小白如何做网站商学院网站建设建议
  • 建站网站图片不显示中国核工业二四建设有限公司实习安排在公司官方网站哪里看?