high-level——单例模式和工厂模式(11)

一、单例模式

  • java设计模式分为三大类,创建型,结构型,行为型

  • 装饰器属于结构型

  • 单例模式属于创建型

  • 单例模式要求某个类的实例在整个应用中只能有一个,实例只能由本类来创建,实例在多线程情况下必须是线程安全的。

  • 在应用中,如果需要某个类的实例只能有一个,比如整个应用都要对同一 个文件进行读写,多个线程要操作同一个变量,多个线程要使用同一个连接对象来操作数据库。

  • spring 中的 Bean 默认都是单例的。

  • 单例可以节约资源,一是对象的创建只有一 次,节省内存,节省创建和销毁的时间。

  • 单例模式的设计原则,必须在类中具有三个要素:

    1. 需要一个静态的属于本类的成员变量。
    2. 构造方法必须是私有的,保证只能在内部创建对象。
    3. 需要一个静态的方法,创建对象并返回对象。保证在没有对象的前提下,可以创建唯一对象并返回对象。
  • 设计形式:

    1. 懒汉型,包括线程安全与非线程安全(加锁,用 synchronized 或可重入锁)只建议单线程情况下使用,不加锁。(使用时才创建)

      package com.zhong.test_6;
      
      public class Lazy {
          private static Lazy lazy;//懒汉型
          private Lazy() {}
          public static Lazy getInstance() {
              if (lazy == null)
                  lazy = new Lazy();
              return lazy;
          }
      }
      
    2. 饿汉型,是线程安全的。初始化时就创建对象。(可能存在浪费资源问题)

      package com.zhong.test_6;
      
      public class Hungry {
          private static Lazy lazy = new Lazy();//饿汉型
          private Lazy() {}
          public static Lazy getInstance() {
              return lazy;
          }
      }
      
    3. 双检锁型,主要用在多线程并发的情况下,并且效率很高。也不会出现资源浪费情况。多线程下最建议使用的。

      package com.zhong.test_6;
      
      public class DoubleCheckLock {
          private static DoubleCheckLock obj;
          private DoubleCheckLock() {}
          public static DoubleCheckLock getInstance() {
              if (obj == null) synchronized (DoubleCheckLock.class) {
                  if (obj == null) {
                      obj = new DoubleCheckLock();
                  }
              }
              return obj;
          }
      }
      
    4. 用枚举类型

    二、设计模式——工厂模式

    • 工厂是越来生产产品的,不同的工厂生产不同的产品。
    • java 中的工厂设计模式,是创建对象的最佳方式。它属于创建型模式。
    • 好处在于,可以隐藏创建对象的逻辑,对象的使用只需要告诉对方我要什么对象就可以了。
    • 工厂模式主要应用于对象的创建等比较繁琐的情形。
    • 使用工厂模式,必须返回接口类型。

    三、线程池

    • 现代的服务器都是多 cpu,线程采用多线程的方式来进行设计,可以更好的利用计算机的资源。如果不考虑多cpu多核的情况,单纯的多线程并不会提高程序的执行效率,相反还会降低效率。在多线程执行的情形下,需要创建线程,销毁线程,切换线程等,线程越多,栈区的内存消耗也越多,所以效率不会提高还会下降。
    1. 为什么还要使用线程池

      • 在多线程并发工作的前提下,如果需要的线程数据比较大,需要线程完成的任务比较多,势必就会产生大量的创建线程,销毁线程,切换线程的额外的工作,这会让系统的效率急剧下降,也容易造成内存泄露。线程池的出现,很好地解决了这个问题。线程池也是 jdk1.5 的新特性。在应用程序开始运行时,一次性创建一定数量的线程,把他们放在池中,如果有任务到达,不需要再去创建线程,直接从池中取出线程让它去执行当前的任务。任务执行完毕,线程仍会回到池中,可以重复使用。应用程序结束前,把线程池销毁。线程池可以极大的提高线程的复用率。
    2. 线程池的结构

      • 有人认为线程池是一个框架,是 jdk 提供的更好利用多线程来进行工作的一个基础框架。

      • 线程池基于一种特定的结构,利用它可以更好地对多线程进行有效的管理,并能够最大限度的节约资源,提升效率。

      • Interface Executor 线程池的基础接口,提供一个 execute() 方法来执行线程的任务。

      • public interface ExecutorService extends Executor

        • submit(Runnable task) 该方法执行线程执行目标(任务),底层调用了 execute()
        • shutdown() 关闭线程池
      • public abstract class AbstractExecutorService extends Object implements ExecutorService 实现了 submit方法

      • public class ThreadPoolExecutor extends AbstractExecutorService

        • 这是实现线程池功能最主要的类,该类的对象就是一个线程池。
        • 它有四个构造方法,构造方法的参数最多有七个,利用这些构造方法可以创建具有功能不同,特性不同的各自线程池。前三个构造方法都是调用第四个构造方法来创建线程池。
      • 线程池的几个主要要素:

        1. 池中线程的数量
        2. 空闲线程的生存时间,可以调整池的工作效率
        3. 任务队列,可分为有界和无界队列两种,有界表示队列中元素的数量是有限的,无界则没有限制。
        4. 线程工厂,线程包含两种,一种是没有返回值的线程(比如Runnable),另外一种有返回值且可以抛异常(Call)。
      • public class Executors extends Object

        • 提供了多种工厂方法,来创建不同特性种类的线程池。如果程序中需要创建线程池,也就是需要使用线程池,可以通过该类的工厂方法类得到线程池对象。该类就是工厂类。
      • 线程池的使用场景

        • 框架,web 应用服务器
        package com.zhong.test_9;
        
        import java.util.concurrent.ExecutorService;
        import java.util.concurrent.Executors;
        
        public class ThreadPoolDemo {
            public static void main(String[] args) {
                // ExecutorService pool1 = Executors.newFixedThreadPool(2);
                ExecutorService pool1 = Executors.newCachedThreadPool();
                pool1.submit((Runnable) () -> {
                    while (true) {
                        try {
                            Thread.sleep(500);
                            System.out.println("一边吃饭");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
        
                pool1.submit((Runnable) () -> {
                    while (true) {
                        try {
                            Thread.sleep(500);
                            System.out.println("一边听歌");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
        
                pool1.submit((Runnable) () -> {
                    while (true) {
                        try {
                            Thread.sleep(500);
                            System.out.println("一边聊天");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
        
                try {
                    Thread.sleep(2000);
                    //  pool1.shutdownNow();//要求没有活动任务时才能关闭
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
继“Java开发微信朋友圈PC版系统-架构1.0”之后,debug这段时间日撸夜撸,终于赶在春节放假前给诸位带来了这一系统的架构2.0版本,特此分享给诸位进行学习,以掌握、巩固更多的技术栈以及项目和产品开发经验,同时也为即将到来的金三银四跳槽季做准备! 言归正传,下面仍然以问答的方式介绍下本门课程的相关内容! (1)问题一:这是一门什么样的课程? 很明显,本门课程是建立在架构1.0,即 第1门课程 的基础上发布的,包含了架构1.0的内容,即它仍然是一门项目、产品实战课,基于Spring Boot2.X + 分布式中间件开发的一款类似“新浪微博”、“QQ空间”、“微信朋友圈”PC版的互联网社交软件,包含完整的门户网前端 以及 后台系统管理端,可以说是一套相当完整的系统! (2)问题二:架构2.0融入了哪些新技术以及各自有什么作用? 本课程对应着系统架构2.0,即第2阶段,主要目标:基于架构1.0,优化系统的整体性能,实现一个真正的互联网社交产品;其中,可以学习到的技术干货非常多,包括:系统架构设计、Spring Boot2.X、缓存Redis、多线程并发编程、消息中间件RabbitMQ、全文搜索引擎Elastic Search、前后端消息实时通知WebSocket、分布式任务调度中间件Elastic Job、Http Restful编程、Http通信OKHttp3、分布式全局唯一ID、雪花算法SnowFlake、注册中心ZooKeeper、Shiro+Redis 集群Session共享、敏感词自动过滤、Java8 等等; A.  基于Elastic Search实现首页列表数据的初始化加载、首页全文检索;B.  基于缓存Redis缓存首页朋友圈“是否已点赞、收藏、关注、评论、转发”等统计数据;整合Shiro实现集群部署模式下Session共享;C.  多线程并发编程并发处理系统产生的废弃图片、文件数据;D.  基于Elastic Job切片作业调度分布式多线程清理系统产生的废弃图片;E.  基于RabbitMQ解耦同步调用的服务模块,实现服务模块之间异步通信;F.  基于WebSocket实现系统后端 与 首页前端 当前登录用户实时消息通知;G.  基于OKHttp3、Restful风格的Rest API实现ES文档、分词数据存储与检索;H.  分布式全局唯一ID 雪花算法SnowFlake实现朋友圈图片的唯一命名;I.  ZooKeeper充当Elastic Job创建的系统作业的注册中心;J.  为塑造一个健康的网络环境,对用户发的朋友圈、评论、回复内容进行敏感词过滤;K.  大量优雅的Java8  Lambda编程、Stream编程;  (3)问题三:系统运行起来有效果图看吗?
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Æ_华韵流风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值