手记

知识体系

1.并发部分

1.    AQS为什么是双向链表

2.    对AQS的理解?大致结构

3.    公平和非公平的实现区别

4.    AQS提供的模板方法和加锁解锁流程

public final void acquire(int arg) {

        if (!tryAcquire(arg) && //交给子类

            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))  加入队列和

            selfInterrupt();

    }

addWaiter cas的方式加入队列尾部 中间的enq包括自旋初始化head tail并确保插入

acquireQueued 自旋尝试前置节点是否是head并获取锁 否则shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt()

shouldParkAfterFailedAcquire

 

5.    共享锁、可中断锁、可控加锁时长锁

6.    ReentrantLock怎么实现的 可重入的实现

7.    ReentrantLock Api和基本用法

8.    ReentrantReadWriteLock的实现逻辑 高16位记录读 低16位记录写

 

9.    ReentrantReadWriteLock 读写锁加锁、释放锁流程

10. Object wait和notify/notifyAll用法 需要结合synchronized  翻书找出基本用法 看下原理

11. Condition的wait和notify/notifyAll用法 及源码 链表是单向的

12. 以上两者的区别 怎么实现生产者消费者

13. LockSupport park进入waiting状态 unPark   synchronized进入blocked

14. Synchronized的应用场景 理解

15. Synchronized的实现原理 优化 偏向所-轻量级锁-重量级锁的锁升级过程

16. ConcurrentHashMap

17. CopyOnWriteArrayList

18. 线程池

COUNT_BITS 29  CAPACITY 29个1 RUNNING 高位111 SHUTDOWN 0 STOP高位001

TIDYING 高位 010 TERMINATED高位 011 通过和CAPACITY的运算计算线程数和状态

 

execute方法:

主流程:

1.workerCountOf(c) < corePoolSize--à addWorker(command, true) ->成功return

2.并列的if 因为并发等原因会存在add失败 (isRunning(c) && workQueue.offer(command)),内部再次检测运行状态 检测通过addWorker(null, false) 注意参数 不通过reject

3.elseif addWorker(command, false) 失败进入reject

 

addWorker流程:

双自旋,外层主要是获取判断运行状态 内层主要是获取在运行数并cas加1(内层判断运行状态 有变则跳出到外层)

包装成worker,通过factory创建线程,worker入HashSet

Worker的runWorker(Worker w)  while(task或者队列获取task)->task.run

没有task进入processWorkerExit

processWorkerExit 从HashSet移除 判断是否应该结束 否->addWorker(null, false);

  

shutdown()方法:

mainLock加锁,checkShutdownAccess 遍历workers—check  advanceRunState修改状态  interruptIdleWorkers中断workers的线程  onShutdown 空方法  最后tryTerminate

shutDownNow方法:

advanceRunState(STOP);状态修改为STOP  drainQueue 移除队列中的任务

 

线程数配置:

Cpu密集 线程数=cup核心数

Io密集 线程数=2cpu核心数

Nthreads=Ncpu*Ucpu*(1+w/c)   w:等待时间 c:计算时间  Ucpu:使用率0~1

Ncpu/(1-阻塞系数)

 

19. ConcurrentLinkedQueue

单向链表,但是有指针指向尾节点

offer主要是利用UNSAFE类进行队列的插入  poll

尾节点延迟更新 叫做HOPS 为了减少cas去更新tail

 

20.  CountDownLatch、CyclicBarrier

两个主方法:await countdown

CountDownLatch:

CyclicBarrier:基于condition  当wait到一定程度 notifyAll

 

21. Semaphore、 Exchanger

Semaphore 可支持公平和非公平 

1.        acquire:利用AQS的acquireSharedInterruptibly

2.        release 利用AQS releaseShared

Exchanger 线程数据交换

exchange:

 

22. ThreadLocal

Get:getMap-每个线程都有一个ThreadLocalMap 获取不到就setInitialValue 其中initialValue默认的是null 再次获取 获取不到创建createMap

Set:getMap createMap

ThreadLocalMap:key为弱引用 开放地址法处理hash冲突(定数:斐波那契数列)  hashMap为分离链表法

弱引用的内存泄露 是因为在用线程池的时候线程不会回收,ThreadLocalMap也不会回收,map中的key是弱引用被回收。 已有优化:get set中会清理掉脏数据

23. 死锁

产生的必要条件:互斥、请求和保持请求、不可剥夺、循环等待

避免:单锁、tryLock。

检测:Jstack JConsole

2.集合部分


0人推荐
随时随地看视频
慕课网APP