实战java高并发程序设计读书概要整理

一、要了解的基本概念
    1、同步和异步:形容一次方法调用,同步要等待返回继续执行;异步调用不需等待返回就可以继续执行
    2、并行和并发:多个任务一起执行,并行是同时执行;并发是交替执行也可能是串行执行
    3、临界区:用来表示一种公共资源或共享数据,每次只能一个线程访问
    4、阻塞和非阻塞:形容多线程之间的相互影响,阻塞是因为某个线程抢占了资源而导致其他线程被挂起,非阻塞则表示线程之间不影响
    5、死锁、饥饿、活锁:线程执行所需的资源被其它线程抢占又得不到释放,造成一直等待资源的状态;饥饿是指一个或多个线程抢占不到不需要的资源,导致无法执行,可能是
    因为低优先级也可能是因为资源被其它线程一直抢占而不释放;活锁指线程间主动释放资源给其它线程使用,导致资源在线程间跳动但线程又都无法获得。
    6、并发级别:阻塞、无饥饿、无障碍、无等待、无锁
        无障碍:是一种最弱的非阻塞调度,认为线程之间不会发生冲突或者是低概率发生,一旦检测到冲突则回滚
    7、java的内存模型(JMM):原子性、可见性、有序性
二、并行程序基础
    1、线程:状态(new,runnable,blocking,waiting,timed_waiting,terminated)
        创建:继承Thread,实现Runnable,线程池newThread(Runnable r)
        停止:不建议用stop()因为可能会造成数据不一致,可建一个volilate变量控制线程退出
        中断:告知线程退出,可用于停止线程
        等待和唤醒;挂起与继续执行;
        等待线程结束(join)和谦让(yield):join可让线程顺序执行,yield是主动让出资源
    2、volatile与JMM:volatile能保证线程的可见性和顺序性但无法保证一些复合操作的原子性
    3、线程组:可以管理一组相同功能的线程,可以获取组内活动线程总数和线程信息
    4、守护线程:一种特殊的后台线程,比如GC线程和JIT线程;用户线程结束之后整个程序也会退出
    5、多并发下的ArrayList和haspMap不安全问题
三、JDK并发包
    1、synchronied的功能扩展之重入锁(ReentrantLock):灵活加锁、中断处理
    2、读写锁(ReadWriteLock):读写分离,读线程完全并行,写线程阻塞
    3、倒计时器(CountDownLatch):countDown()、await()
    4、循环栅栏计数器(CyclicBarrier):构造方法和await()
    5、线程阻塞工具类(LockSupport):park()与unpark()
    6、线程池:管理线程,避免反复创建和销毁线程带来的系统开销,让线程可复用
    (1)JDK支持:Executors->ThreadPoolExecutor,默认的4种实现实际上均是对ThreadPoolExecutor的封装
    (2)ThreadPoolExecutor(int corePoolSize, //核心线程数,默认会一直存活即使是闲置状态
                              int maximumPoolSize, //最大线程数,超过核心数后创建的为非核心线程,闲置时会被回收
                              long keepAliveTime, //非核心线程闲置超时时间
                              TimeUnit unit,    //超时单位
                              BlockingQueue<Runnable> workQueue, //核心线程都在工作时,新的任务加入列队,队列已满则创建非核心线程执行任务
                              ThreadFactory threadFactory, //线程工厂,指定线程创建方式
                              RejectedExecutionHandler handler) //异常处理
    (3)ThreadFactory
     (4) 优化线程池线程数量:Ncpu(计算密集型) ~ 2Ncpu(IO密集型
     (5) 异常堆栈的输出
    7、分而治之:Fork/Join框架
    8、并发容器java.util.concurrent包
        ConcurrentHashMap:高效的并发HashMap
        CopyOnWriteArrayList:读多写少场景性能非常好,远好于Vector
        ConcurrentLinkedQueue:高效并发队列,链表实现
        BlockingQueue:阻塞队列--ArrayBlockingQueue与LinkedBlockingQueue
四、锁的优化
1、优化:
    1.1、减少锁的持有时间,必要时进行同步
    1.2、减少锁粒度,例如ConcurrentHashMap的put实现?
    1.3、读写分离锁代替独占锁
    1.4、锁分离,例如LinkedBlockingQueue中take和put
    1.5、锁粗化:JVM在遇到一连串对同一锁不断进行请求和释放的操作时,会把所有的锁操作合并为对锁的一次请求
2、ThreadLocal:线程安全的线程局部变量
  用处:1)实现单个线程单例以及单个线程存储上下文信息
    2)实现线程安全
    3)承载线程相关数据,避免在方法中来回传递
  原理:ThreadLocal的值是放入当前线程的一个ThreadLoaclMap实例中,所以只能在当前线程访问,其它线程访问不到
  思考:真的只有一个线程可以访问吗?InheritableThreadLocal可以将某个线程的ThreadLocal值在其子线程创建的时候传递过去
    会导致内存泄露吗?ThreadLocalMap在选择key的时候,并不是直接选择ThreadLocal实例,而是ThreadLocal实例的软引用,所以不会产生内存泄露
3、无锁策略CAS(Compare and Swap)
  CAS(V, E, N) : 要修改的值,预期值,新值
4、无锁的线程安全整数AtomicInteger
5、让线程之间互相帮助:SynchronousQueue的实现:
  特殊的容量为0的等待队列,核心方法为Object transfer(Object e, boolean timed, long nanos)
6、死锁
  哲学家用餐示例,相互之间只得到部分资源而占用其它人所需必要资源但不释放,造成相互之间无限等待
五、并行设计模式与算法
1、单例模式
  好处:省略new操作的时间花费,减少系统开销;降低内存使用频率,减少GC开销;
  推荐方式:静态内部类初始化实例,无锁且高效
2、不变模式:为了尽可能去除同步操作,提高并行程序效率,使用一种不可改变的对象,依靠对象的不变性在多线程环境中依然保持内部的一致性和正确性
  使用场景满足条件:对象创建后,其内部状态和数据不再发生任何变化;对象需要共享,被多线程频繁访问。
  实现:所有属性私有且final标识;去重setter方法和一切修改属性的方法;确保没有子类可以重载它的行为;有一个可以构造完整对象的构造函数
  JDK中应用:String,Boolean,Byte,Integer等包装类型
3、Disruptor实现生产者消费者模型
  CPU cache的优化,解决伪内存共享问题,cache line使用value+padding方式,避免value修改造成的缓存失效问题
  @sun.misc.Contended代替padding变量解决伪共享问题
4、Future模式
  核心思想:异步调用
5、并行流水线
6、NIO
  channel(通道) + buffer(缓冲区) + selector(选择器)
六、java8与并发
1、java8的函数式编程
  函数可以作为另外一个函数的返回值,是函数式编程重要的特点之一
  基本无副作用的申明式编程方式
  几乎所有传递的对象都不会轻易的被修改
  易于并行,因为对象是不变的状态
2、FunctionalInterface注释
3、Lamda表达式:使用的变量需定义为final或视为final,即不能修改,否则会报错
4、方法引用
5、并行流与并行排序:parallel
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值