reentrantlock和synchronized区别
reentrantlock:可重入锁
实现了AQS(一系列cas操作[比如进出队列等]+volatile int state同步状态标识+用LockSupport.park LockSupport.unpark 休眠和**队内线程)
trylock
有等待队列
公平锁,非公平锁
状态锁
synchronized
锁升级 偏向锁 自旋锁 重量级锁
CountDownLatch:
门栓 数量门栓:不到指定的值,门栓阻塞不放行
lanch.countDown() 一般用于子线程方法给门栓值加一
latch.await();一般用于主线程阻塞着,等上边的方法将值加到一定值后放行
CyclicBarrier:
栅栏 等的数量多了冲开栅栏
cyclicBarrier.await() 一般用于子线程中调用阻塞等待,却等待数自动加1,等待的数量一旦到了指定值子线程们同时放行
ReadWriteLock 读与写互斥,写与写互斥,读与读不互斥可同时
Semaphore 发信号 信号量
用于限流执行
s.acquire能拿到信号的执行,拿不到阻塞
s.release释放信号
、
Exchanger 交换器 线程间交换信息(放满两个就互相交换),没放满之前阻塞在那
锁分类 乐观锁(CAS\自旋锁) 、 悲观锁(重量级锁,系统级锁 ,synchronized升级到最高级别锁)、 偏向锁(对象头打线程标记)、 自旋锁(while配合CAS)
读写锁(读锁是共享锁,写锁是排它锁)、 分段锁(ConcurrentHashMap或者LongAdder等中有用到)
synchronized(lock)中lock.wait()指当前线程让出锁,并退出cpu的竞争 lock.notify[all]指唤醒一个或所有其他停止竞争cup的再次参与竞争但是不释放锁,还是要等到主动释放锁或者走出synchronized其他的竞争者才能得到锁,补充wait与sleep的区别wait是锁对象的方法阻塞让锁,sleep是Thread的静态方法仅用于阻塞线程一段时间
AQS为一系列同步器依赖于一个单独的原子变量(state)的同步器提供了一个非常有用的基础。子类们必须定义改变state变量的protected方法,这些方法定义了state是如何被获取或释放的。鉴于此,本类中的其他方法执行所有的排队和阻塞机制。子类也可以维护其他的state变量,但是为了保证同步,必须原子地操作这些变量。
AbstractQueuedSynchronizer中对state的操作是原子的,且不能被继承。所有的同步机制的实现均依赖于对改变量的原子操作。为了实现不同的同步机制,我们需要创建一个非共有的(non-public internal)扩展了AQS类的内部辅助类来实现相应的同步逻辑。
AQS的实现类
reentrantlock:可重入锁
CountDownLatch:门栓
CyclicBarrier:栅栏
Semaphore:发信号 信号量
ThreadLocal :
ThreadLocal 的set或者get的内部原理先去获取当前线程拥有的ThreadLocalMap(Thread类中属性),set时存往map中的key是this当前的ThreadLocal对象,所以一般都是配合static使用使得当前线程中使用的是同一个ThreadLocal,get反之
强引用:一般对象都是
软引用:gc时容量不够,将其牺牲gc掉
弱引用:gc时直接gc,但是弱还有一个强引用指向还是不回收 弱引用使用案例eg:ThreadLocal上图 WeakHashMap
虚引用:JVM中用于管理堆外内存用的(下图),程序中基本用不到
容器
线程:
并发:同时发生(不一定同时执行,比如多线程抢占一个CPU) 并行:同时执行(两个线程分别在两个CPU执行) 因此并行也属于并发的一种
CompletableFuture面试不怎么问但是很多场景很实用
顺便一提 JMH用于性能压力测试
disruptor
目前单机性能最高的MQ,号称单机吞吐最快的消息队列
RingBuffer 环形缓冲区,消费位置标识
详细参考: https://www.cnblogs.com/pku-liuqiang/p/8544700.html