1、公平锁、非公平锁
- 公平锁:非常公平,不能插队,必须先来后到。
- 非公平锁:非常不公平,可以插队(synchronized和lock默认都是非公平锁)
//默认为非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
2、可重入锁
可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁。
![](https://img.haomeiwen.com/i24360436/12c5cce7c8b9cf13.png)
Synchronized:
//测试可重入锁:synchronized
public class reentrant {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.email();
},"A").start();
new Thread(()->{
phone.email();
},"B").start();
new Thread(()->{
phone.call();
},"C").start();
}
}
class Phone{
public synchronized void email(){
System.out.println(Thread.currentThread().getName()+"->email");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
call(); //该方法也加了锁
}
public synchronized void call(){
System.out.println(Thread.currentThread().getName()+"->call");
}
}
******************************结果:**********************************
A->email
A->call
C->call
B->email
B->call
ReentrantLock:
//测试可重入锁:ReentrantLock
public class TestReentrantLock {
public static void main(String[] args) {
Phone2 phone = new Phone2();
new Thread(()->{
phone.email();
},"A").start();
new Thread(()->{
phone.email();
},"B").start();
new Thread(()->{
phone.call();
},"C").start();
}
}
class Phone2{
Lock lock = new ReentrantLock();
public synchronized void email(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"->email");
TimeUnit.SECONDS.sleep(2);
call(); //该方法也加了锁
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public synchronized void call(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"->call");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
***************************结果:*****************************
A->email
A->call
C->call
B->email
B->call
网友评论