1、原始构成:
synchronized是关键字,属于JVM层面,底层是由一对monitorenter和monitorexit指令实现的。
ReentrantLock是一个具体类,是API层面的锁。
2、使用方法:
synchronized不需要用户手动释放锁,当synchronized代码块执行完成后,系统会自动让线程释放对锁的占用
ReentrantLock需要用户手动释放锁,若没有手动释放可能导致死锁现象。
3、等待是否可中断:
synchronized不可中断,除非抛出异常或者正常运行完成
ReentrantLock可中断
4、加锁是否公平:
synchronized非公平锁
ReentrantLock两者都可以,默认是非公平锁。
5、锁绑定多个条件Condition:
synchronized没有。
ReentrantLock可用来分组唤醒需要唤醒的线程。而不是像synchronized要么随机唤醒一个线程,要么唤醒所有线程。
题目:多线程之间按顺序调用,实现A->B->C三个线程启动,要求如下:
* AA打印5次,BB打印10次,CC打印15次
* 紧接着
* AA打印5次,BB打印10次,CC打印15次
* 来10轮
class ShareResource { private int number = 1; private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); public void print5() { lock.lock(); try { while (number != 1) { condition1.await(); } for (int i = 1; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } number = 2; condition2.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void print10() { lock.lock(); try { while (number != 2) { condition2.await(); } for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } number = 3; condition3.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void print15() { lock.lock(); try { while (number != 3) { condition3.await(); } for (int i = 1; i <= 15; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } number = 1; condition1.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } public class SyncAndReentrantLockDemo { public static void main(String[] args) { ShareResource shareResource = new ShareResource(); new Thread(() -> { for (int i = 0; i < 10; i++) { shareResource.print5(); } }, "AAA").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { shareResource.print10(); } }, "BBB").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { shareResource.print15(); } }, "CCC").start(); } }