并发包中ReentrantLock的建立能够指定构造函数的boolean类型来获得公平锁或者非公平锁,默认是非公平锁java
公平锁
:在并发环境中,每一个线程在获取锁时会先查看此锁维护的等待队列,若是为空,或者当前线程是等待队列中的第一个,就占用锁,不然就会加入到等待队列中,之后会按照FIFO的规则从队列中等待被取到。api
非公平锁
:非公平锁比较粗鲁上来就直接尝试占有锁,若是尝试失败,就在采用相似公平锁的方式在队列中等待被取到。并发
对于java ReentrantLock而言,经过构造函数指定该锁是否为公平锁,默认是非公平锁
。非公平锁的优势自安于吞吐量比公平锁大。jvm
对于synchronized而言,也是一种非公平锁函数
可重入锁又叫递归锁,典型的可重入锁有ReentrantLock/Synchronized。指的是统一鲜橙外层函数得到锁以后,内层度规函数仍然能获取该锁的代码,同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁
也就是说,线程能够进入任何一个他已经拥有的锁所同步着的代码块。post
public synchronized void method01(){
method02();
}
public synchronized void method02(){
}
复制代码
如以上代码,若是一个线程拥有method01的锁,那么会自动拥有method02的锁,这样看,可重入锁最大的做用是避免死锁this
可参考上篇文章介绍的CAS的加锁方式atom
public final int getAndSetInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var4));
return var5;
}
复制代码
自旋锁是指获取锁的线程不会当即阻塞,而是采用循环的方式去尝试获取锁直至成功为止,没有相似wait的阻塞,这样的好处是减小线程上下文切换的消耗,缺点是循环会消耗CPUspa
手动实现一个自旋锁:线程
public void myLock(){
Thread thread = Thread.currentThread();
System.out.println(thread +": come in lock");
while (!atomicReference.compareAndSet(null,thread)){
}
}
public void unLock(){
Thread thread = Thread.currentThread();
System.out.println(thread + ": come in unlock");
while (!atomicReference.compareAndSet(thread,null)){
}
}
复制代码
当A线程调用myLock时,thread为null,因此atomicReference.compareAndSet(null,thread)成立,取反跳出循环,这时atomicReference内Thread为A的线程,B线程同时也调用myLock方法时,由于指望值为null,其实是A线程,结果不成立,因此一直在while中循环;A线程再调用unlock方法,指望值是A本身的线程,而后设置为null,返回true而后取反,跳出循环,B线程不断地在mylock中循环,忽然读到指望值为null了,知足本身的需求,而后跳出循环,这时加锁成功。
独占锁:该锁一次只能被一个线程所持有,ReentrantLock和Synchronized都是独占锁
共享锁:该锁可被多个线程所持有。 ReentrantReadWriteLock中的读锁是共享锁,其写锁是独占锁。 读锁的共享锁可保证并发读是很是高效的,读写,写读,写写的过程是互斥的。
让一些线程阻塞直到另外一些线程完成一系列操做后才被唤醒 CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其余线程调用countDown方法会将计数器减1(调用countDown方法的线程不会被阻塞),当计数器的值变成零时,因调用await方法被阻塞的线程会被唤醒,继续执行。
CyclicBarrier意思Wie可循环使用的屏障。主要功能是让一组线程到达一个屏障点(也能够叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,被屏障拦截的线程才会继续干活,线程进入屏障经过CyclicBarrier的await()方法。 demo: 集齐7颗龙珠才能召唤神龙
Semaphore 信号量,主要用于两个目的,一个是用于多个共享资源的互斥使用,另外一个用于并发线程数的控制。