synchronized和ReentrantLock的区别
- synchronized是一个关键字,是JVM内部实现的;ReentrantLock是标准库的一个类,是JVM外部基于Java实现的。
- synchronized在申请锁失败时会死等;ReentrantLock可以通过tryLock的方式等待一段时间就放弃。
- synchronized使用时不需要手动释放锁;ReentrantLock使用时需要手动释放锁,它更加灵活,但是容易忘记unlock。
- synchronized是一个非公平锁;ReentrantLock默认是非公平锁,但它可以通过在构造方法中传入一个true开启公平锁模式。
- ReentrantLock的唤醒机制比synchronized更加强大,synchronized是通过Object类的wait/notify实现等待-唤醒,且每次唤醒的是一个随机等待的线程;ReentrantLock搭配Condition类实现等待-唤醒,可以更加精确的控制唤醒某个指定的线程。
三个线程交替打印ABC案例(ReentrantLock搭配Condition展现的指定唤醒功能):
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Demo_4 {
static ReentrantLock loker = new ReentrantLock();
static Condition A = loker.newCondition();
static Condition B = loker.newCondition();
static Condition C = loker.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
loker.lock();
for (int i = 0; i < 10; i++) {
A.await();
B.signal();
System.out.println("A");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
loker.unlock();
}
});
Thread t2 = new Thread(() -> {
try {
loker.lock();
for (int i = 0; i < 10; i++) {
B.await();
C.signal();
System.out.println("B");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
loker.unlock();
}
});
Thread t3 = new Thread(() -> {
try {
loker.lock();
for (int i = 0; i < 10; i++) {
C.await();
A.signal();
System.out.println("C");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
loker.unlock();
}
});
t1.start();
t2.start();
t3.start();
Thread.sleep(1000);
try {
loker.lock();
A.signal();
} finally {
loker.unlock();
}
}
}
- synchronized是基于操作系统的mutex锁实现的;ReentrantLock是基于CAS和AQS实现的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)