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

网站发布文章怎么才能让百度收录网络推广方案有哪些

网站发布文章怎么才能让百度收录,网络推广方案有哪些,网站开发的前端语言是哪些,快速搭建一个网站目录 1 单例模式的程序结构 2 饿汉式单例模式的实现 3 饿汉式线程安全 4 防止反射破坏单例 5 总结 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。所谓单例就是在系统中只有一个该类的实例,并且提供一个访问该实例的全局…

       

目录

1 单例模式的程序结构

2 饿汉式单例模式的实现

3 饿汉式线程安全

4 防止反射破坏单例

5 总结


       单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。所谓单例就是在系统中只有一个该类的实例,并且提供一个访问该实例的全局访问方法。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式,关于单例模式的原理,可参考文末的链接文章。

       单例的实现分为三个步骤:

  1. 构造方法私有化。即不能在类外实例化,只能在类内实例化。
  2. 在本类中完成自身的初始化,自己创建本类的实例,且是唯一的实例。
  3. 在本类中提供给外部获取实例的方式,提供访问该实例的全局静态方法getInstance(),来获取该类的唯一实例引用。

       单例模式的特点:从系统启动到终止,整个过程只会产生一个实例。因为单例提供了唯一实例的全局访问方法,所以它可以优化共享资源的访问,避免对象的频繁创建和销毁,从而可以提高性能。单例模式常见的应用场景如下:Windows任务管理器、数据库连接池、Java中的Runtime、Spring中Bean的默认生命周期等。

1 单例模式的程序结构

        单例模式简化后的类图如下所示:

        类图显示了该类的一个私有静态成员变量、一个公有静态方法(又叫静态成员函数)以及一个私有的构造函数。虽然这是简化后的结构,但也是单例模式的主要结构。顺便说一下,这个类图只是个简化后的结构,该类通常还会有其它的非静态的成员变量和方法,当获取到该类的唯一实例后,就在该实例上调用这些其它方法来执行该类提供的功能。

        私有的构造函数保证只能在类内部实例化;静态成员变量用来保存该类的唯一实例,该静态成员变量必须是private的,以防止用户可以直接访问到它。如果用户想要访问该单例类的唯一实例,它只能调用该类的静态方法(getInstance)。

       注意static(静态成员变量、静态方法)的使用。从语法上来说,创建的单例类是不允许被其他程序用new来创建该对象的,所以只能将这个单例类中的方法定义成静态的,而静态方法又不能去访问非static成员的,所以因此类自定义的实例变量也必须是静态的。

       这里不妨回顾一下,静态成员变量是属于整个类的,仅在类的初次加载时初始化,在类被销毁时才会被回收。通过该类实例化的所有对象都共享该静态变量,任一对象对于该静态变量的修改都会影响所有的对象。静态方法同样是属于整个类的,可以通过类名与对象名进行访问,而非静态成员是随着对象的创建而被实例化的。在调用静态方法时,可能对象还没有实例化,自然也就没有对象的非静态成员的实例化,所以无法访问非静态的成员。

2 饿汉式单例模式的实现

       在Java中实现单例模式通常有两种形式.:

  • 饿汉式:类加载时,就进行对象实例化。
  • 懒汉式:第一次引用类时,才进行对象实例化。

      这里主要聚焦于饿汉式。饿汉式代码实现如下:

public class HungrySingLeton {// 创建HungrySingLeton 的一个对象private static final HungrySingLeton instance = new HungrySingLeton();// 让构造函数为private,这样该类就不会被实例化private HungrySingLeton() {}// 获取唯一可用的对象public static HungrySingLeton getInstance(){return instance;}/*** 获取对象的内存地址* @return*/public long getRamAddress() {return VM.current().addressOf(this);}
}

       注意instance变量加了final的,一般建议加final,除非说有释放资源等特殊要求。这种方式简单,也比较常用,在类创建的同时已经创建好一个静态的对象供系统使用,执行效率高。

3 饿汉式线程安全

       饿汉式单例通过getInstance获取的单例,在类加载时已经初始化完毕,在多线程环境下也是安全的,所以不需要同步。我们可以通过测试来验证。

       先写一个公共方法,用于多线程环境下获取单例:

    /*** 公共方法,在多线程环境下获取单例,避免重复编写测试代码* @param threadCount  线程数* @param func  函数,用于获取单例* @param <T>*/public static <T> List<T> getSingLetonObjList(int threadCount, Supplier<T> func) {List<T> list = new ArrayList<>();ExecutorService executorService = Executors.newFixedThreadPool(threadCount);IntStream.range(0, threadCount).forEach(i -> {executorService.submit(() -> {// 同步锁,保证保证内存的可见性,否则在多线程环境下可能出现空对象synchronized (SingletonTest.class) {list.add(func.get());}});});executorService.shutdown();while(true) {// 所有的子线程都结束了if(executorService.isTerminated()) {if(list.size() == threadCount) {return list;}}}}

       这个公共方法可以接收一个函数,该函数就是获取单例的方法。值得注意的是那个同步锁,如果不加的话,在多线程环境下,可能会获得空的单例导致后续调用getRamAddress方法时出现空指针。当然,也可以用Sytem.out.print方法代替:

synchronized (SingletonTest.class) {list.add(func.get());
}等价于:System.out.print("");
list.add(func.get());

       因为print方法本身就自带锁:

public void println(String x) {synchronized (this) {print(x);newLine();}
}

       有了公共方法后,接着写测试代码:

    public static void hungrySingLetonTest() {Supplier func = () ->  HungrySingLeton.getInstance();List<HungrySingLeton> list = getSingLetonObjList(10, func);list.stream().forEach(item -> {System.out.println("内存地址: " + item.getRamAddress());});}

       测试结果如下:

       多线程下获取到的单例始终是同一个对象,他们的内存地址都一样。

4 防止反射破坏单例

       到这里,可能会认为已经很OK了。但是,Java还有个反射机制,通过反射,可以轻易破解单例的安全。

    public static void reflectionTest() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {Class<HungrySingLeton> clazz = HungrySingLeton.class;// 获取HungrySingLeton的默认构造函数Constructor<HungrySingLeton> constructor = clazz.getDeclaredConstructor();constructor.setAccessible(true);// 调用默认构造函数创建实例HungrySingLeton h1 = constructor.newInstance();HungrySingLeton h2 = constructor.newInstance();System.out.println(h1.getRamAddress());System.out.println(h2.getRamAddress());}

       得到的结果如下:

       是两个对象实例!既然反射是先获得class(也是类的实例),再通过calss获得构造函数,去获取单例,那么解决办法就是在饿汉式构造函数中,同步类:

public class HungrySingLeton {// 创建HungrySingLeton 的一个对象private final static HungrySingLeton instance = new HungrySingLeton();// 让构造函数为private,这样该类就不会被实例化private HungrySingLeton() {// 防止防止反射破坏单例synchronized (HungrySingLeton.class) {if(instance != null){throw new RuntimeException("单例构造器禁止反射调用");}}}// 获取唯一可用的对象public static HungrySingLeton getInstance(){return instance;}/*** 获取对象的内存地址* @return*/public long getRamAddress() {return VM.current().addressOf(this);}
}

       测试结果如下:

5 总结

       饿汉式单例这种方式简单,也比较常用,在类创建的同时已经创建好一个静态的对象供系统使用,执行效率高。但这种方式下,因为还未调用对象就已经创建,造成资源的浪费,容易产生垃圾对象。

http://www.hyszgw.com/news/283.html

相关文章:

  • 网站建设需求怎么提百度搜索推广官网
  • 个人网站做影视整合网络营销外包
  • 泉州做网站的潍坊网站开发公司
  • 网站建设小程序开发站长综合查询工具
  • 可以免费看日本黄片的app做网站邵阳疫情最新消息
  • 名聚优品一家只做正品的网站天津网站优化
  • 域名租赁网站千峰培训出来好就业吗
  • 保定公司网站建设自媒体营销代理
  • 交友网站开发术平台推广方式有哪些
  • 苏州企业网站制作电话搜索风云榜
  • 南京制作网站建站模板公司企业产品营销策划推广
  • 营销型网站设计服务商网络营销推广平台
  • 外包网站建设报价百度平台app
  • 莱州相亲网站手机黄页怎么找
  • 网站建设的栏目软件推广赚钱一个10元
  • 中小企业建站bing搜索引擎入口官网
  • 地方政府网站建设免费seo诊断
  • 网站建设 找vx cp5173软文推广文案
  • 做的好的营销型网站有哪些内容自己怎么优化网站
  • 展厅设计用什么软件谷歌seo关键词优化
  • 学工系统网站建设的意义搜索引擎营销的简称是
  • 酒店品牌设计网站建设百度推广外推联系方式
  • 网站成功案例怎么做建网站费用
  • 简述网站设计规划的步骤如何销售自己产品方法有哪些
  • 外贸型网站方案西安网站搭建
  • wordpress反应网站优化招聘
  • 泉州一个网站多少钱哪些行业适合做网络推广
  • 工商局网站如何做网登长春网站制作设计
  • pc做网站服务器吗关键词代发排名
  • 企业网站设置费用注册城乡规划师好考吗