0%

ThreadPool

初始化线程池后,把任务丢进去,等待调度就可以了,使用起来比较方便。
JAVA中Thread是线程类,不建议直接使用Thread执行任务,在并发数量比较多的情况下,每个线程都是执行一个很短的时间就任务结束了,这样频繁创建线程会大大降低系统的效率,因为频繁的创建和销毁线程需要时间。而线程池可以复用,就是执行完一个任务,并不销毁,而是可以继续执行其它任务。

Thread的弊端

  • 每次new Thread() 创建对象,性能差。
  • 线程缺乏统一管理,可能无限制创建线程,相互竞争,有可能占用过多系统资源导致死机或OOM。
  • 不能多执行,定期执行,线程中断

线程池的优点

  • 重用存在的线程,减少对象创建,消亡的开销,性能佳,降低资源消耗。
  • 可以控制最大并发线程数,提高系统资源利用率,同时避免过多资源竞争,避免阻塞,提高响应速度。
  • 提供定时执行,定期执行,单线程,并发数控制等功能,以提高线程的可管理性。

阿里发布的 Java 开发手册中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

Executors利用工厂模式向我们提供了4种线程池实现方式,但是并不推荐使用,原因是使用Executors创建线程池不会传入相关参数而使用默认值所以我们常常忽略了那些重要的参数(线程池大小、缓冲队列的类型等),而且默认使用的参数会导致资源浪费,不可取。

阅读全文 »

设计模式学习方法及实践

学习

  • 牢记类的继承/实现关系
  • 多记模式在现实中对应的场景

实践

  • 抽象类的职责
  • 多看源码的实践及解决的问题

常用实践

  • 单例
    • 全局配置
    • 无状态实体
  • 工厂
    • HashMap
  • 模板
    • 流程固定,实现类多
      • redisTemplate/jdbcTemplate
  • 监听
    • 领域事件
  • 策略
    • 一个借口,多个Bean实现
  • 适配
    • 实体类转换
  • 代理
    • 统一封装第三方接口调用

阅读源码方式

寻找入口

  • Tomcat-Main函数
  • Debug常用方法

划分模块/组件

  • 模块名,包名
  • 套用设计模式

串联链路

  • Request/Response
  • SpringBean
  • SQL

事务

ACID

  • Atomicity

    原子性(Atomicity):事务中的操作要么都做,要么都不做。

  • Consistency
    一致性(Consistency):系统必须始终处在强一致状态下

  • Isolation
    隔离性(Isolation):一个事务的执行不能被其他事务所干扰

  • Durability

    持续性(Durability):一个已提交的事务对数据库中数据的改变是永久性的

BASE

概念

  • Basically Avaliable
    基本可用(Basically Available):系统能够基本运行、一直提供服务
  • Soft-state
    状态(Soft-state):系统不要求一直保持强一致状态
  • Eventual consistency
    最终一致性(Eventual consistency):系统需要在某一时刻后达到一致性要求

主要实现方式

  • 两阶段型
    分布式事务两阶段提交,对应技术上的XA、JTA/JTS。这是分布式环境下事务处理的典型模式
  • 补偿型
    TCC型事务(Try/Confirm/Cancel)可以归为补偿型;TCC思路是:尽早释放锁;在Try成功的情况下,如果事务要回滚,Cancel将作为一个补偿机制,回滚Try操作;
    TCC各操作事务本地化,且尽早提交 (放弃两阶段约束);当全局事务要求回滚时,通过另一个本地事务实现“补偿”行为;
    TCC是将资源层的两阶段提交协议转换到业务层,成为业务模型中的一部分;
  • 异步确保型
    将一些同步阻塞的事务操作变为异步的操作,避免对数据库事务的争用,典型例子是热点账户异步记账、批量记账的处理
  • 最大努力通知型
    交易的消息通知与失败重试(例如商户交易结果通知重试、补单重试)

模式分类

  • 异步确保
  • 重试与幂等
  • 可补偿操作

CAS

什么是CAS

CAS(compare and swap),字面意思比较并交换,是解决多线程并行情况下使用锁造成性能损耗的一种机制.

1
2
3
public final boolean compareAndSet(int expect, int update) {        
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

CAS有三个操作数,valueOffset内存值,expect期望值,update要更新的值。如果内存值(valueOffset)和期望值(expect)是一样的。那么处理器会将该位置的值更新为(update),否则不做任何操作。

CAS 有效地说明了“我认为位置valueOffset应该包含值expect,如果包含该值,则将update放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”在 Java 中,sun.misc.Unsafe类提供了硬件级别的原子操作来实现这个 CAS,java.util.concurrent包下的大量类都使用了这个Unsafe类的 CAS 操作

阅读全文 »

MySQL 分库分表

什么是分库分表

分库分表其实很好理解,「顾名思义,即把存于一个库的数据分散到多个库中,把存于一个表的数据分散到多个表中」。但是需要明确一点,分库分表不是一件事,而是三件事,也就是「分库分表的三种方案」

  • 「只分库不分表」
  • 「只分表不分库」
  • 「既分库又分表」
阅读全文 »

ThreadLoacl的理解

ThreadLocal提供了线程的局部变量,每个线程都可以通过set()和get()来对这个局部变量进行操作,但不会和其他线程的局部变量发生冲突,实现了线程的数据隔离

简言之:往ThreadLoacl中填充的变量属于当前线程,该变量对其他线程而言是隔离的。

ThreadLocal可以让我们拥有当前线程的变量

常用的方法

  • set(T value):设置线程本地变量的内容。
  • get():获取线程本地变量的内容。
  • remove():移除线程本地变量。注意在线程池的线程复用场景中在线程执行完毕时一定要调用remove,避免在线程被重新放入线程池中时被本地变量的旧状态仍然被保存。
阅读全文 »

Volatile

volatile的中文意思是不稳定的、易变的,用volatile修饰的变量是为了保证变量的可见性

  • Volatile作用:用来确保将变量的更新操作通知到其他线程

  • 原理:

    1)编译器会注意到被volatile修饰的变量是共享的,因此不会将该变量上的操作与其他内存操作一起重新排序

    volatile变量不会被缓存在寄存器中,因此读取volatile变量总会返回最新的值

    2)在访问volatile变量时,不会执行加锁操作,因此也不会阻塞线程,对非volatile变量进行读写时,每个线程先从内存拷贝变量到CPU缓存中

    总结:不会重排、不会缓存(永远是最新值)、不会加锁(因此不会阻塞)

阅读全文 »

DDD与中台、微服务的关系

  • 什么是中台
  • 企业中台组成
  • 基于DDD的微服务设计
  • 微服务拆分和设计原则
  • 中台、微服务与DDD的关系
阅读全文 »

AQS

介绍:

  • 用途:是并发包的一个基础组件,用来实现各种锁,各种同步组件。ReentrantLock就是用AQS实现的

    比如,Semaphore用它来表现剩余的许可数,ReentrantLock用它来表现拥有它的线程已经请求了多少次锁;FutureTask用它来表现任务的状态等。

    使用 AQS 来实现一个同步器需要覆盖实现如下几个方法,并且使用getStatesetStatecompareAndSetState这三个方法来操作状态。

  • AQS全称:AbstractQueuedSynchrinizer,抽象队列同步器。

阅读全文 »