• 多线程新手村3--多线程代码案例


    1.1 单例模式

    单例模式是设计模式中非常经典的一种。那么有同学肯定就会好奇了,什么是设计模式呢?

    设计模式简单的说就是程序员的“棋谱”,我们下象棋时肯定或多或少都背过棋谱,例如当头炮、马后炮等,设计模式也是这样,开发过程中常常会遇到一些经典场景,用固定的解决方案去解决这些问题,这就是设计模式,今天我们先来介绍一下单例模式。

    单例模式是指某个类只能实例化一个对象,不能有多个,这一点在很多场景中都会用到,例如数据库中的DateSource实例就只需要一个;单例模式又有两种实现方式,分别为饿汉模式和懒汉模式。

    1.1.1 饿汉模式

    在类加载的时候,创建实例(比较急切)

    可以看到,由于将构造方法设为私有,所以当我们想要自己实例化一个对象的时候,编译器会报错,此时,这个类将只会有加载类时实例化的那一个对象,无法再实例化出其它对象。

    1.1.2 懒汉模式

    只有当需要的时候才创建实例

    上述代码可以看出,只有当首次调用getInstance方法时才会创建实例,否则将不会创建实例。

    单线程中懒汉模式没有问题,但是放在多线程中,就会存在许多bug!

    1.1.3 懒汉模式(多线程版)

    首先要解决一个疑惑,为什么饿汉模式的单线程都不会有bug,但是懒汉模式的多线程会存在bug呢?是因为饿汉模式的getInstance方法只有读功能,但是懒汉模式的getInstance方法却既可读又可写,两个线程对于同一个变量进行写操作,就很容易出现问题。所以我们要加锁,将操作变为原子性的,这样就不会出现问题了。

    1、这里的加锁是为了保证原子性操作,防止代码出bug(new多个对象出来)

    2、这里再一次判断对象是否为空是为了确定要不要加锁,因为如果不加这个代码的话,每次调用这个方法都会加锁,但是加锁很费时,效率很低,不好!

    3、此处的volatile关键字是为了防止出现指令重排序问题。

    1.2 阻塞队列

    阻塞队列是多线程代码中常用的一种数据结构。

    所谓阻塞队列,其实就是加了阻塞功能的队列。

    a)如果队列为空,继续出队列,就会发生阻塞,直到其它线程向队列中加入元素。

    b)如果队列为满,继续入队列,也会发生阻塞,直到其它线程向队列中取走元素。

    阻塞队列,最大的意义是用来实现“生产者消费者模型”

    “生产者消费者”模型的意义:

    1、解耦合(单独设置一个队列,使原本两个直接进行数据交互的元素通过这个队列进行交互)

    2、削峰填谷

    当数据请求量很大的时候,如果没有阻塞队列的话,服务器A一直给服务器B发数据,就可能使服务器B崩溃;但是如果设置一个阻塞队列,那么A只需要将数据放入队列中,如果B此时已达到最大处理负荷的话,那B只需要慢慢的取出队列中的数据处理即可;反之,如果此时数据请求量很小,那么服务器B就可以慢慢地消耗掉堆积在阻塞队列中的数据。

    1.3 阻塞队列的代码实现

    以上代码就是自己实现了一个简易的阻塞队列,可以用作一个简单的“生产者消费者”模型。注意两个wait和notify都是互相唤醒的,无法自己唤醒自己。

  • 相关阅读:
    十九、一起学习Lua 垃圾回收
    Python笔记 之 简单并发任务(线程/进程池)
    【CSS】flex布局,
    Java中过滤器与拦截器的使用
    什么是 SEO 垃圾邮件攻击?
    Android recycleview瀑布流中间穿插一行占满一屏
    AJAX的使用,搭建web服务器,AJAX响应消息类型,JSON
    Java面试进阶指北
    戏剧影视设计制作虚拟仿真培训课件提升学生的参与感
    汇编语言快速回顾(以x86_64为例)
  • 原文地址:https://blog.csdn.net/qq_62872261/article/details/139244887