先说说常见锁工具的理解
一、ReentrantLock:重入锁,递归锁,轻量锁,悲观锁
public class A implements java.lang.Runnable{
java.util.concurrent.locks.Lock reentrantLock = new java.util.concurrent.locks.ReentrantLock();
int threadName;
public A(int threadName){
this.threadName = threadName;
}
public void run(){
System.out.println(this.threadName+"开始");
doA();
}
public void doA(){
reentrantLock.lock();
System.out.println(this.threadName+"开始doA");
doB();
reentrantLock.unlock();//最好finally代码块执行
System.out.println(this.threadName+"完成doA");
}
public void doB(){
reentrantLock.lock();
System.out.println(this.threadName+"开始doB");
reentrantLock.unlock();
System.out.println(this.threadName+"完成doB");
}
}
二、Synchronized:重入锁,递归锁,重量锁,悲观锁
代码楼上方法改用synchronized即可
三、ReentrantReadWirteLock:读写锁,读读共存,读写,写写不共存,
多个线程操作缓存数据,确保操作的原子性,且优化了。读读共存操作。
java.util.concurrent.locks.ReentrantReadWriteLock readWriteLock = new java.util.concurrent.locks.ReentrantReadWriteLock();
java.util.HashMap<Integer, Integer> hashMap = new java.util.HashMap<Integer,Integer>();
public class AA implements java.lang.Runnable{
java.util.concurrent.locks.Lock readLock;
java.util.HashMap<Integer, Integer> hashMap;
int threadName;
public AA(int threadName,java.util.concurrent.locks.ReentrantReadWriteLock readWriteLock,java.util.HashMap<Integer, Integer> hashMap){
this.threadName = threadName;
this.readLock = readWriteLock.readLock();
this.hashMap = hashMap;
}
public void run(){
for(int i=0;i<100;i++){
doA(i);
}
}
public void doA(int i){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.readLock.lock();
System.out.println(this.threadName+"开始doA 读");
System.out.println(this.threadName+" 读取 "+hashMap.get(i));
System.out.println(this.threadName+"完成doA 读");
this.readLock.unlock();
}
}
public class BB implements java.lang.Runnable{
java.util.concurrent.locks.Lock writeLock;
java.util.HashMap<Integer, Integer> hashMap;
int threadName;
public BB(int threadName,java.util.concurrent.locks.ReentrantReadWriteLock readWriteLock,java.util.HashMap<Integer, Integer> hashMap){
this.threadName = threadName;
this.writeLock = readWriteLock.writeLock();
this.hashMap = hashMap;
}
public void run(){
for(int i=0;i<100;i++){
doB(i);
}
}
public void doB(int i){
writeLock.lock();
System.out.println(this.threadName+"开始doB 写");
hashMap.put(i, i);
System.out.println(this.threadName+"完成doB 写");
writeLock.unlock();
}
}
四、CAS(compare and swap)锁:无锁机制,乐观锁,无阻赛,无等待,数据库乐观锁(版本字段控制)
经典使用:原子工具类
CAS(V,E,N)
E,预期值(本地内存)
N,新值、
V,要更新的值(主内存)
V和E相等,主内存与本地内存一致,V设置成N新值
V和E不相等,主内存与本地内存不一致,更新本地内存值,再回到楼上V和E相等操作。
也就是要操作前,读取本地内存值与主内存值是否相等,也就是V要更新值与E期望值是否一致,不一致把主内存值给本地内存,再更新N新值。
有毛病:若本地内存值与主内存值一致,这中间给人轮奸过呢。再一致呢
五、自旋锁
while(Thread.activeCount() != 1){
//wait
}
System.out.println("线程给唤醒后,或进入阻塞前,继续占用cpu工作空指令,等待获取锁,自旋等待,到这一步已经等待到了");
一切锁来源与AQS框架的实现,AbstractQueuedSynchronizer的实现