(1)synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。 ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。
(2)synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock 也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。
(3)synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以响应中 断。
ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,一个 最主要的就是ReentrantLock还可以实现公平锁机制。什么叫公平锁呢?也就是在锁上等待时间最长的 线程将获得锁的使用权。通俗的理解就是谁排队时间最长谁先执行获取锁。
public class T6 {
//原子类用于计数
volatile AtomicInteger num = new AtomicInteger(50);
//true 开启公平锁
ReentrantLock lock = new ReentrantLock(true);
public static void main(String[] args) {
T6 t = new T6();
new Thread(t::min, "T1").start();
new Thread(t::min, "T2").start();
new Thread(t::min, "T3").start();
new Thread(t::min, "T4").start();
new Thread(t::min, "T5").start();
new Thread(t::min, "T6").start();
new Thread(t::min, "T7").start();
}
void min() {
while (true) {
//synchronized (this) {
if (num.get() > 0) {
//加锁
lock.lock();
num.decrementAndGet();
System.out.printf("%s卖出了一票,剩余%d票%n", Thread.currentThread().getName(), num.get());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//为零的时候退出循环
if (num.get() < 1) {
break;
}
//解锁
lock.unlock();
// }
}
}
}
}
结果为: