中间件

  • 软件胶水
  • 不是操作系统、不是数据库管理系统、不是软件应用一部分,
  • 而是让软件开发者方便处理通信、输入和输出、专注业务应用部分
  • 桥梁作用

三个领域的中间件

  • 远程过程调用和对象访问中间件
  • 分布式环境下应用的互相访问
  • 应用服务化的基础
  • 消息中间件
  • 解决应用之间消息传递、解耦、异步的的问题
  • 数据访问中间件
  • 解决访问数据库的共性问题的组件

java 中间件 坑_数据库

  • 使用线程池、使用有固定上限的线程池
  • 线程创建消耗很大
  • synchronized
  • 使用修饰代码块的方式比较灵活,直接修饰方法不灵活
  • 互斥效果
  • 同步本地线程变量值和主存一致
  • ReentrantLock(重入锁)
  • 用法类似synchronized,不过需要显式 unlock
  • 引入原因:
  • 提供了tryLock 方法
  • 返回false代表锁被其他线程持有,不能获取;
  • true代表没被其他线程持有,获取成功。
  • 构建ReentrantLock 时,有一个构造函数参数是Boolean 类型
  • 描述锁公平与否,
  • 公平锁严格排队(效率低一些);
  • 非公平锁抢占式(效率高点)
  • ReentrantLock 提供了ReentrantReadWriteLock 
  • 主要用于读多写少,并且读不需要互斥的场景
  • 这样使用读写锁会比全部互斥的锁性能高很多
  • volatile
  • 保证了所修饰变量的可见性
  • 轻量级实现变量可见性的方法
  • 更多修饰开关状态的变量(取值不会使用本地线程副本)
  • 如下图(在读的层面)
  • i3  synchronized 关键词,保证了本地线程副本与主存同步,也是最新的
  • i2 取值不会使用本地线程副本,是最新的
  • i1 可能不是最新的

java 中间件 坑_python_02

  • 如下图,在写的层面
  • i1 设置后会立即得到最新值,其他线程不一定
  • i2 volatile 保证变量仅仅在主存保存一份,其他线程立即能看到最新值
  • i3  synchronized 关键字,会把本地副本同步到主存,但是别的线程查看不一定和主存一致(除非也加上synchronized ,先同步本地副本和组从在读取)

java 中间件 坑_数据库_03

  • volatile 仅仅保证可见性,put 不是线程安全的
  • 所以多线程下面代码最后的 count 可能会大于100
  • 加上synchronized  轻松搞定

java 中间件 坑_java 中间件 坑_04

  • Atomics包
  • 提供一些原子操作 
  • 与自己手动同步相比,使用简单线程安全,性能高很多
  • 性能高很多的原因是使用了硬件支持的指令

java 中间件 坑_java 中间件 坑_05

  • wait、notify、notifyAll 使用时必须放在synchronized 块里面
  • 实际应用中,wait外面套循环,防止虚假唤醒

java 中间件 坑_数据库_06

  • CountDownLatch
  • 等所有都执行完countDown后,wait才会被唤醒
  • countDown执行完countDown ,该线程不会阻塞,而是继续自己的工作

java 中间件 坑_java_07

java 中间件 坑_python_08

  • CyclicBarrier(字面意思:循环屏障、栅栏)
  • 等所有线程都到达await,一起开始执行
  • 也就是说提前到达await的线程会阻塞在这里
  • 因此使用时请小心,线程池小的话,很容易死锁
  • 每个线程都带一个await,循环外也带一个await,所以是count+1个
  • CountDownLatch 不能循环使用 CyclicBarrier 可以

java 中间件 坑_数据库_09

java 中间件 坑_数据库_10

java 中间件 坑_java_11

  • Semaphore用于管理信号量,构造时传入可供管理信号量数量
  • 如果管理的信号量数量为1,Semaphore退化为互斥锁
  • 大于1 的时候,主要用于控制最大并发数,超过最大并发量就阻塞等待并发量降下来在执行
  • 执行前acquire方法 获取信号量(获取不到就会阻塞),release 释放
  • acquire 和release 可以带参数,参数的含义就是获取、返还信号量个数

java 中间件 坑_java_12

  • ExChanger 用于两个线程之间进行数据交换
  • 线程会阻塞在ExChanger 的exchange 方法,直到另一个线程也执行到同一个ExChanger 的exchange 方法
  • 二者进行交换,然后继续执行自己的方法

java 中间件 坑_java_13

java 中间件 坑_python_14

  • Future(接口) 和 FutureTask(具体实现类)

并发容器

动态代理

反射

  • 反射本质是生成动态代理来执行该方法
  • newInstance 创建对象时,一定要有无参构造函数,否则会抛异常
  • 字节码增强
  • Javassist
  • cglib
  • asm
  • ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。
  • ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。
  • Java class 被存储在严格格式定义的 .class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。
  • ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
  • bcel

java 中间件 坑_主存_15

java 中间件 坑_java 中间件 坑_16