1 synchronize是jvm层面,底层是monitorenter和monitorexit实现的;lock是具体类,api层面的锁
2 synchronize不需要手动释放锁,当锁住的代码块儿执行完后就会自动释放。lock则需要手动调用unlock释放锁
3 synchronize等待不可中断,除非抛异常或者方法正常完成。
lock可中断,设置超时方法tryLock(timeout, timeunit)或lockInterruptibly()放代码块,调用interrupt()中断
4 synchronize只能加非公平锁,lock可以加公平锁也可以加非公平锁
5 synchronize只能随机唤醒一个线程要么全部唤醒,lock可以精确唤醒。
实现功能:从线程1开始,按照线程1,线程2,线程3的顺序每个线程轮流打印从1到5,总计打印10次
/**
* print方法
* @param j 第几次大循环
* @param expectNum 执行的线程设置的标识
* @param expectCondition 正在执行的condition
* @param afterNum 下一个线程执行的标识
* @param afterCondition 下个执行的condition
* @throws InterruptedException
*/
private void print(int j, int expectNum, Condition expectCondition, int afterNum, Condition afterCondition) throws InterruptedException {
// 加锁
reentrantLock.lock();
while (number != expectNum) {
// 当前线程设置的expectNum!=正在执行的number则进行让步
expectCondition.await();
}
// 执行打印任务
for (int i = 0; i < 5; i ++) {
System.out.println(j + "->" + Thread.currentThread().getName() + "->" + i);
}
// 设置下一个执行标志位
number = afterNum;
// 唤醒后一个线程
afterCondition.signal();
// 释放资源
reentrantLock.unlock();
}
测试代码
private volatile int number = 1;
private ReentrantLock reentrantLock = new ReentrantLock();
private Condition c1 = reentrantLock.newCondition();
private Condition c2 = reentrantLock.newCondition();
private Condition c3 = reentrantLock.newCondition();
@Test
public void multiConditionTest() throws InterruptedException {
// 三个线程,轮流执行print方法10次
new Thread(() -> {
for (int i = 0; i < 10; i ++) {
try {
print(i, 1, c1, 2, c2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "线程1").start();
new Thread(() -> {
for (int i = 0; i < 10; i ++) {
try {
print(i, 2, c2, 3, c3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "线程2").start();
new Thread(() -> {
for (int i = 0; i < 10; i ++) {
try {
print(i, 3, c3, 1, c1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "线程3").start();
TimeUnit.MINUTES.sleep(1);
}
测试结果
0->线程1->0
0->线程1->1
0->线程1->2
0->线程1->3
0->线程1->4
0->线程2->0
0->线程2->1
0->线程2->2
0->线程2->3
0->线程2->4
0->线程3->0
0->线程3->1
0->线程3->2
0->线程3->3
0->线程3->4
1->线程1->0
1->线程1->1
1->线程1->2
1->线程1->3
1->线程1->4
1->线程2->0
1->线程2->1
1->线程2->2
1->线程2->3
1->线程2->4
1->线程3->0
1->线程3->1
1->线程3->2
1->线程3->3
1->线程3->4
2->线程1->0
2->线程1->1
2->线程1->2
2->线程1->3
2->线程1->4
2->线程2->0
2->线程2->1
2->线程2->2
2->线程2->3
2->线程2->4
2->线程3->0
2->线程3->1
2->线程3->2
2->线程3->3
2->线程3->4
……