Note-Concurrency
发布日期:2022-02-24 11:35:59 浏览次数:6 分类:技术文章

本文共 2541 字,大约阅读时间需要 8 分钟。

高并发(high concurrency)

缓存一致性协议(MESI)

Modified Exclusive Shared Invalid
修改的 独享的 共享的 无效的

注:乱序执行优化

Java内存模型(JMM)

1.读取(Read)载入(Load),存储(Store)写入(Write)必须成对出现

2.不允许丢弃赋值(Assign),必须存储(Store),写入(Write)
3.没有赋值(Assign),不允许存储(Store),写入(Write)
4.没有读取(Read)载入(Load),不允许使用(Use)
5.变量不能被多个线程锁定(Lock),锁定(Lock)解锁(Unlock)次数相等
6.锁定(Lock)之后会清空线程值,使用需重新读取(Read)载入(Load)
7.没有进行锁定(Lock),不允许进行解锁(Unlock)
8.解锁(Unlock)时必须存储(Store)写入(Write)


1.线程安全性:多线程无视调度方式,不需额外同步协同,能表现出正确行为

  1. 原子性:互斥访问,同一时刻只有一个线程进行操作
    1. AtomicXXX : Unsafe类CAS实现
      存在ABA问题(AtomicStampedReference解决)
    2. Synchronized : 依赖JVM锁
      局部锁(当前对象):修饰代码块,修饰方法
      全局锁(所有对象):代码块中锁对象为XXX.class,修饰静态方法
    3. Lock : 依赖特殊的CPU指令
      ReetrantLock : 可重入锁
  2. 可见性:一个线程对主内存的修改可以被其他线程观察到
    1. 原因:交叉运行,乱序优化,修改未及时同步
    2. Synchronized : 锁定后清空,解锁时写入
    3. Volatile : 加入XY屏障,禁止重排序(禁止屏障前X与屏障后Y重排)
      写操作在前加storestore,在后加storeload屏障
      读操作在后加loadload和loadstore屏障
  3. 有序性:观察线程指令执行顺序,由于指令重排造成结果无序
    Java保证指令重排不影响单线程,happens-before原则

2.安全发布对象

  1. 发布对象:是一个对象能够被当前范围之外的代码使用
  2. 对象逸出:当一个对象还没有完全构造完成时就被其他线程所见
  3. 安全发布
    1. 静态初始化函数中初始化一个对象
    2. 将对象引用保存到volatile类型域或AtomicReference对象中
    3. 将对象引用保存到正确构造对象的final域中
    4. 将对象引用保存到由锁保护的域中

3.线程安全策略

  1. 不可变对象(共享只读):
    创建以后不可修改,final修饰所有域,无this逸出,
    不可变的集合:Collections.unmodifiableXXX , ImmutableXXX…
  2. 线程封闭(线程限制):局部变量,ThreadLocal
  3. 同步容器(线程安全对象):
    Vector , Stack,HashTable , Collections.synchronizedXXX…
  4. 并发JUC容器(被守护对象):
    CopyOnWriteArrayList , CopyOnWriteArraySet , ConcurrentSkipListSet , ConcurrentHashMap , ConcurrentSkipListMap…

4.JUC之AQS:AbstractQueuedSynchronizer

  1. CountDownLatch , 线程等待
  2. Semaphore , 信号量
  3. CyclicBarrier , 线程并进
  4. ReentrantLock:
    与synchronized的区别:可重入,依靠AQS实现,性能好,功能多
    独有功能:可选择公平性,可Condition分组唤醒,能中断等待锁
    其他:StampedLock,ReentrantReadWriteLock
  5. 扩展:
    FutureTask : 实现Runnable和Future接口,有返回结果的异步任务
    ForkJoin : 密集计算任务拆分进行,任务密取
    BlockingQueue : 阻塞队列,生产者和消费者模式

5.线程池

  1. ThreadPoolExecutor
    Executors.newCachedThreadPool
    Executors.newFixedThreadPool
    Executors.newScheduledThreadPool
    Executors.newSingleThreadExecutor
  2. 参考配置
    计算密集型:CPU数量+1
    IO密集型:CPU数量*2

死锁

条件:互斥,请求和保持,不剥夺,环路等待

最佳实践:

  1. 使用本地变量
  2. 使用不可变类
  3. 最小化锁的作用域s=1/(1-a+a/n)
  4. 使用线程池,而不是Thread
  5. 使用同步工具,而不是wait,notify
  6. 使用BlockingQueue实现生产消费者模式
  7. 使用并发集合,而不是同步集合
  8. 使用Semaphore创建有界访问
  9. 使用同步代码块,而非同步方法
  10. 使用不可变的静态变量

优化思路:

  1. 扩容
    服务器(垂直扩展/水平扩展)
    数据库(读扩展:Memcache,redis,CDN/写扩展:Cassandra,Hbase)
  2. 缓存(本地缓存:编程实现,GuavaCache/分布式缓存:Memcache,Redis)
    因素:命中率:业务需求,粒度策略,容量基础/最大元素/清空策略
    问题:一致,并发,穿透,雪崩
  3. 消息队列
    特点:只做分发,先进先出,容灾,性能
    优点:业务解耦,最终一致,广播,流控
    Kafka,RabbitMQ,ActiceMQ,RocketMQ…
  4. 应用拆分
    原则:业务优先,循序渐进,兼顾技术,可靠测试
    思考:通信机制选择,数据库设计,避免跨应用
  5. 应用限流
    算法:计数器法,滑动窗口,漏桶算法,令牌桶算法
  6. 熔断降级
    共性:目的,表现,粒度,自治
    区别:触发原因,管理目标层次,实现方式
  7. 切库分库分表
    瓶颈:数据量,吞吐量
    切库:读写分离
    分表:横向,纵向
  8. 高可用
    任务调度系统分布式:elastic-job+zookeeper
    主备切换:apache-curator+zookeeper分布式锁实现
    监控报警

转载地址:https://blog.csdn.net/Hyosung_Han/article/details/105411012 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:依赖倒置原则「Dependence Inversion Principle」
下一篇:CentOS7搭建Java开发环境

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月21日 01时48分01秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章