JAVA线程间的共享和协作
线程间的共享
隐式锁synchronized 和显示锁Lock:
synchronized
1.Sychronized(非公平锁)的用法: a.对象锁,锁的是类的对象实例 b.类锁,锁的是每个类的Class对象,每个类的Class 对象在虚拟机中只有一个;所以类锁只有一个; c.锁方法块; 2.性能和执行效率: 同步方法体<小对象锁代码块
Lock
Lock是一个接口,提供无条件,可轮询的,定时的,可中断的锁获取操作;所有的加锁和解锁是显示的; 实现方法: 1.ReentrantLock:默认为非公平锁,ReentrantLock(true)公平锁 注:在一个时间内,先对锁进行获取的请求,一定先被满足,称之为公平锁,反只是非公平锁; 非公平锁的效率一般比公平锁的效率更高; 2.ReentrantReadWriteLock(接口) 读写锁:每次需要获取共享数据就需要读取锁,修改共享数据需要写入锁; 注:读写锁机制: a.读-读不互斥,读线程可以并发执行; b.读-写互斥,有写线程时,读线程会阻塞; c.写-写互斥,写线程都是互斥的。
Synchronized、ReentrantLock和ReentrantReadWriteLock
1.Synchronized 是JVM层面的,无需显示的加解锁;ReentrantLock 和 ReentrantReadWriteLock 是显示层面,一定要手动加解锁,保证锁资源被释放; 2.ReentrantReadWriteLock 引入了读写和并发机制;可以实现复杂的业务场景;并发性相对Synchronized 和ReentrantLock 更高; 3.Synchronized 的阻塞无法中断,ReentrantLock则提供了可中断的阻塞。
volatile 关键字
确保可见性,线程不安全;适合一写多读的线程; 原理说明:CUP的运行速度远高于内存的读写数据,现代cpu和内存之间都存在一个高速缓存cache(实际上是一个多级寄存器) 线程运行的过程中,会把主内存数据拷贝一份到线程内部cache中,也就是work memory,这时多线程访问同一个变量就是访问自己内部的 cache; volatile 变量的内存可见性是基于内存屏障(Memory Barrier)实现; 实现原理参考:https://www.jianshu.com/p/ccfe24b63d87
ThreadLocal
ThreadLocal:线程变量;可以理解为:Map<Thread,Object>:
ThreadLocal 出现内存泄漏的原因:多线程运行时,每个线程强引用ThreadLocal Map;当线程结束后,强引用失效,但是ThreadLocalRef 还存在弱引用; 解决办法:当某个ThreadLocal 的变量(比如:TL_INT)不在使用时,调用TL_INT.remove(),删除该Key;
线程池使用ThreadLocal时,可以达到线程复用的效果,但是归还线程时,需要清除threadLocalMap; 重写hreadPoolExecutor.afterExecute方法; 具体原理及内存泄漏问题请参考:https://blog..net/puppylpg/article/details/80433271
CAS原子操作
1.原子操作是不可被中断的一个或一系列操作;在JAVA中可以通过锁(lock/syn) 和循环CAS来实现原子操作;
循环CAS实现原子操作
1.java中的CAS操作就是利用了处理提供的CMPXCH指令实现的,自旋CAS实现实现的基本思路就是循环进行CAS操作直至成功; 2.CAS实现原子操作的三大问题: a.ABA问题:如果值开始为A,然后变成B,又变成A,CAS检查会发现值没有变化,实际变化了;解决思路:使用版本号,在变量上添加版本号,每次变化版本号加1;ABA就会变成1A-2B-3C;java中提供AtomicStampedReference来解决; b.循环时间长,开销大问题,会给CPU带来非常大的执行开销 c.只能保证一个共享变量的原子操作,如果要操作多个共享变量,就需要加锁;
3.JDK提供的原子操作类: a.更新基本类型:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference; b.更新数组类型:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray; c.更新引用类型:AtomicReference,AtomicMarkableReference,AtomicStampedReference d.原子更新字段类型:AtomicReferenceFieldUpdater,AtomicIntegerFieldUpdater,AtomicLongFieldUpdater
abstractqueuedsynchronizer AQS 分析
具体参考:https://yq.aliyun.com/articles/686676