synchronized和lock的区别
1. synchronized是jvm层面的,lock是API层面的锁
- 使用如下代码验证
public class LockAndSynchronizedDemo {
public static void main(String[] args) {
synchronized (new Object()){
}
new ReentrantLock();
}
}
- 使用
javap -c LockAndSynchronizedDemo.class
得到字节码指令
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/Object
3: dup
4: invokespecial #1 // Method java/lang/Object."<init>":()V
7: dup
8: astore_1
9: monitorenter
10: aload_1
11: monitorexit
12: goto 20
15: astore_2
16: aload_1
17: monitorexit
18: aload_2
19: athrow
20: new #3 // class java/util/concurrent/locks/ReentrantLock
23: dup
24: invokespecial #4 // Method java/util/concurrent/locks/ReentrantLock."<init>":()V
27: pop
28: return
- 注意点
synchronized
关键字解析出三条关键字节码指令,一条monitorenter
,两条monitorexit
(一个monitorexit是发生异常退出,一个monitorexit是正常退出)new ReentrantLock()
只是执行了一条new对象的指令,证明了是代码层面的实现,和JVM底层没啥大关系
2. synchronized不需要解锁
- synchronized不需要向lock一样执行
lock.unlock()
操作
3. 等待是否可中断
- synchronized不可以被中断,要等待就得一直等待
- lock可以使用
lock.interrupt()
方法进行中断,在等待期间去干别的事
4. synchronized是非公平锁
- synchronized是非公平锁,不可更改
- lock可以通过构造函数指定是公平锁还是非公平锁
5. 锁绑定多个条件Condition(精准唤醒)
1. synchronized要么notify(),要么notifyAll(),线程之间的唤醒方式太过单一
2. lock可以精准唤醒,conditionA可以唤醒conditionB,conditionB可以唤醒conditionC
精准唤醒的Condition代码举例
- A打印五次,C打印十次,B打印15次
//A打印五次,C打印十次,B打印15次
public class PrintDemo {
public static void main(String[] args) {
PrintSource printSource = new PrintSource();
new Thread(() -> {
printSource.print5();
},"AAA").start();
new Thread(() -> {
printSource.print10();
},"BBB").start();
new Thread(() -> {
printSource.print15();
},"CCC").start();
}
}
class PrintSource{
private Lock lock = new ReentrantLock();
private Integer number = 1;
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
public void print5(){
lock.lock();
try {
while(number != 1){
condition1.await();
}
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"\t "+i);
}
number = 2;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void print10(){
lock.lock();
try {
while(number != 2){
condition2.await();
}
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"\t "+i);
}
number = 3;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void print15(){
lock.lock();
try {
while(number != 3){
condition3.await();
}
for (int i = 0; i < 15; i++) {
System.out.println(Thread.currentThread().getName()+"\t "+i);
}
number = 1;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/202549.html