1.原始构成
- synchronized是关键字属于JVM层面,
monitorentry(底层是通过monitor对象来完成,其wait/notify等方法也是依赖于monitor对象只有在同步块或方法中才能调用wait/notify等方法)
monitorexit - Lock是具体类(java.util.concurrent.locks.lock)是api层面的锁
2.使用方法
- synchronized不需要用户去手动释放锁,当synchronized代码执行完后系统会自动让线程释放对锁的占用
- ReentrantLock则需要用户去手动释放锁若没有释放锁,就有可能导致出现死锁的现象。需要lock()和unlock()方法配合try/finally语句块来完成。
3.等待是否可中断
- synchronized不可中断,除非抛出异常或者正常运行完成
- ReentrantLock可中断
- 1.设置超时方法tryLock(long timeout,TimeUnit unit)
- 2.lockInterruptibly()放代码块中,调用interrupt()方法中断
4.加锁是否公平
- synchronized非公平锁
- ReentrantLock两者都可以,默认非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁
5.锁绑定多个条件Condition
- synchronized没有
- ReentrantLock用来实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个线程,要么唤醒全部线程
锁绑定多个条件Condition:
题目:多线程之间按顺序调用,实现A->B->C 三个线程启动,要求如下:
A打印5次,B打印10次,C打印15次,紧接着
A打印5次,B打印10次,C打印15次
。。。
来10轮
示例代码:
class ShareResource {
private int number = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5(int n) {
try {
lock.lock();
while (number != 1) {
//等待
c1.await();
}
//打印
for (int i = 1; i <= 5; i++) {
System.out.println(n + "轮" + Thread.currentThread().getName() + "\t" + i);
}
//设置标志位
number = 2;
//唤醒下一个线程
c2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(int n) {
try {
lock.lock();
while (number != 2) {
//等待
c2.await();
}
//打印
for (int i = 1; i <= 10; i++) {
System.out.println(n + "轮" + Thread.currentThread().getName() + "\t" + i);
}
//设置标志位
number = 3;
//唤醒下一个线程
c3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15(int n) {
try {
lock.lock();
while (number != 3) {
//等待
c3.await();
}
//打印
for (int i = 1; i <= 15; i++) {
System.out.println(n + "轮" + Thread.currentThread().getName() + "\t" + i);
}
//设置标志位
number = 1;
//唤醒下一个线程
c1.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 = 1; i <= 10; i++) {
shareResource.print5(i);
}
}, "A").start();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareResource.print10(i);
}
}, "B").start();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareResource.print15(i);
}
}, "C").start();
}
}
运行结果:
1轮A 1
1轮A 2
1轮A 3
1轮A 4
1轮A 5
1轮B 1
1轮B 2
1轮B 3
1轮B 4
1轮B 5
1轮B 6
1轮B 7
1轮B 8
1轮B 9
1轮B 10
1轮C 1
1轮C 2
1轮C 3
1轮C 4
1轮C 5
1轮C 6
1轮C 7
1轮C 8
1轮C 9
1轮C 10
1轮C 11
1轮C 12
1轮C 13
1轮C 14
1轮C 15
2轮A 1
2轮A 2
2轮A 3
2轮A 4
2轮A 5
2轮B 1
2轮B 2
2轮B 3
2轮B 4
2轮B 5
2轮B 6
2轮B 7
2轮B 8
2轮B 9
2轮B 10
2轮C 1
2轮C 2
2轮C 3
2轮C 4
2轮C 5
2轮C 6
2轮C 7
2轮C 8
2轮C 9
2轮C 10
2轮C 11
2轮C 12
2轮C 13
2轮C 14
2轮C 15
3轮A 1
3轮A 2
3轮A 3
3轮A 4
3轮A 5
3轮B 1
3轮B 2
3轮B 3
3轮B 4
3轮B 5
3轮B 6
3轮B 7
3轮B 8
3轮B 9
3轮B 10
3轮C 1
3轮C 2
3轮C 3
3轮C 4
3轮C 5
3轮C 6
3轮C 7
3轮C 8
3轮C 9
3轮C 10
3轮C 11
3轮C 12
3轮C 13
3轮C 14
3轮C 15
4轮A 1
4轮A 2
4轮A 3
4轮A 4
4轮A 5
4轮B 1
4轮B 2
4轮B 3
4轮B 4
4轮B 5
4轮B 6
4轮B 7
4轮B 8
4轮B 9
4轮B 10
4轮C 1
4轮C 2
4轮C 3
4轮C 4
4轮C 5
4轮C 6
4轮C 7
4轮C 8
4轮C 9
4轮C 10
4轮C 11
4轮C 12
4轮C 13
4轮C 14
4轮C 15
5轮A 1
5轮A 2
5轮A 3
5轮A 4
5轮A 5
5轮B 1
5轮B 2
5轮B 3
5轮B 4
5轮B 5
5轮B 6
5轮B 7
5轮B 8
5轮B 9
5轮B 10
5轮C 1
5轮C 2
5轮C 3
5轮C 4
5轮C 5
5轮C 6
5轮C 7
5轮C 8
5轮C 9
5轮C 10
5轮C 11
5轮C 12
5轮C 13
5轮C 14
5轮C 15
6轮A 1
6轮A 2
6轮A 3
6轮A 4
6轮A 5
6轮B 1
6轮B 2
6轮B 3
6轮B 4
6轮B 5
6轮B 6
6轮B 7
6轮B 8
6轮B 9
6轮B 10
6轮C 1
6轮C 2
6轮C 3
6轮C 4
6轮C 5
6轮C 6
6轮C 7
6轮C 8
6轮C 9
6轮C 10
6轮C 11
6轮C 12
6轮C 13
6轮C 14
6轮C 15
7轮A 1
7轮A 2
7轮A 3
7轮A 4
7轮A 5
7轮B 1
7轮B 2
7轮B 3
7轮B 4
7轮B 5
7轮B 6
7轮B 7
7轮B 8
7轮B 9
7轮B 10
7轮C 1
7轮C 2
7轮C 3
7轮C 4
7轮C 5
7轮C 6
7轮C 7
7轮C 8
7轮C 9
7轮C 10
7轮C 11
7轮C 12
7轮C 13
7轮C 14
7轮C 15
8轮A 1
8轮A 2
8轮A 3
8轮A 4
8轮A 5
8轮B 1
8轮B 2
8轮B 3
8轮B 4
8轮B 5
8轮B 6
8轮B 7
8轮B 8
8轮B 9
8轮B 10
8轮C 1
8轮C 2
8轮C 3
8轮C 4
8轮C 5
8轮C 6
8轮C 7
8轮C 8
8轮C 9
8轮C 10
8轮C 11
8轮C 12
8轮C 13
8轮C 14
8轮C 15
9轮A 1
9轮A 2
9轮A 3
9轮A 4
9轮A 5
9轮B 1
9轮B 2
9轮B 3
9轮B 4
9轮B 5
9轮B 6
9轮B 7
9轮B 8
9轮B 9
9轮B 10
9轮C 1
9轮C 2
9轮C 3
9轮C 4
9轮C 5
9轮C 6
9轮C 7
9轮C 8
9轮C 9
9轮C 10
9轮C 11
9轮C 12
9轮C 13
9轮C 14
9轮C 15
10轮A 1
10轮A 2
10轮A 3
10轮A 4
10轮A 5
10轮B 1
10轮B 2
10轮B 3
10轮B 4
10轮B 5
10轮B 6
10轮B 7
10轮B 8
10轮B 9
10轮B 10
10轮C 1
10轮C 2
10轮C 3
10轮C 4
10轮C 5
10轮C 6
10轮C 7
10轮C 8
10轮C 9
10轮C 10
10轮C 11
10轮C 12
10轮C 13
10轮C 14
10轮C 15