【JUC】synchronizated和lock的区别&新lock的优势

原始构成

synchronized是关键字,属于JVM层面

javap -c 的结果显示

synchronized是可重入锁

11:是正常退出 17:是异常退出【保证不产生死锁和底层故障】

Lock是java.util.concurrent.locks包中的一个接口 是API层面的锁

使用方法

synchronized不需要yoghurt手动释放锁,当synchronized代码执行完后系统自动让线程释放对锁的占用

ReentrantLock则需要用户手动释放没有主动释放的锁,可能出现死锁现象。需要lock、unlock和try/catch一起使用

等待是否可中断

synchronizated不可中断,除非抛出异常或者正常运行完成

reentrantLock可中高端

  • 设置超时方法tryLock 【new ReentrantLock().tryLock(1,TimeUnit.SECONDS);】
  • lockInterruptibly()放代码块中,调用interrupt()方法中断【new ReentrantLock().lockInterruptibly();】

是否是公平锁

synchronizated是非公平锁

reentrantLock源码:默认是非公平锁。也可以传参true为公平锁 false为非公平锁

 1     /**
 2      * Creates an instance of {@code ReentrantLock}.
 3      * This is equivalent to using {@code ReentrantLock(false)}.
 4      */
 5     public ReentrantLock() {
 6         sync = new NonfairSync();
 7     }
 8 
 9     /**
10      * Creates an instance of {@code ReentrantLock} with the
11      * given fairness policy.
12      *
13      * @param fair {@code true} if this lock should use a fair ordering policy
14      */
15     public ReentrantLock(boolean fair) {
16         sync = fair ? new FairSync() : new NonfairSync();
17     }

锁是否绑定多个条件Condition

synchronizated没有,只能随机唤醒一个(notify()),或者唤醒全部唤醒(notifyAll())

ReentrantLock用来实现分组唤醒需要唤醒的线程,可以精确唤醒某个线程。

例如:多线程之间按顺序调用 实现线程之间按顺序启动【精确唤醒的举例】

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.Lock;
 3 import java.util.concurrent.locks.ReentrantLock;
 4 
 5 /**
 6  * 一个拍照的景点 有3个人要按顺序排单人照
 7  * 张三想要拍1张 李四想要拍3张 王五想要拍5张
 8  * 他们按照这个顺序排了两个景点
 9  */
10 class Plat{
11     private int id = 1; // 3人的编号
12     private Lock lock = new ReentrantLock();
13     private Condition person1 = lock.newCondition();
14     private Condition person2 = lock.newCondition();
15     private Condition person3 = lock.newCondition();
16     public void person1TakePhoto(){
17         lock.lock();
18         try{
19             while (id != 1){
20                 person1.await();
21             }
22             for (int i = 0; i < 1; i++) {
23                 System.out.println(Thread.currentThread().getName()+ "拍了"+(i+1)+"张照片");
24             }
25             id = 2;
26             person2.signal();
27         }catch(Exception e){
28             e.printStackTrace();
29         }finally{
30             lock.unlock();
31         }
32     }
33     public void person2TakePhoto(){
34         lock.lock();
35         try{
36             while (id != 2){
37                 person2.await();
38             }
39             for (int i = 0; i < 3; i++) {
40                 System.out.println(Thread.currentThread().getName()+ "拍了"+(i+1)+"张照片");
41             }
42             id = 3;
43             person3.signal();
44         }catch(Exception e){
45             e.printStackTrace();
46         }finally{
47             lock.unlock();
48         }
49     }
50     public void person3TakePhoto(){
51         lock.lock();
52         try{
53             while (id != 3){
54                 person3.await();
55             }
56             for (int i = 0; i < 5; i++) {
57                 System.out.println(Thread.currentThread().getName()+ "拍了"+(i+1)+"张照片");
58             }
59             id = 1;
60             person1.signal();
61         }catch(Exception e){
62             e.printStackTrace();
63         }finally{
64             lock.unlock();
65         }
66     }
67 
68 }
69 public class ReentantLockTest {
70     public static void main(String[] args) throws InterruptedException {
71         Plat plat = new Plat();
72         new Thread(()->{
73             for (int i = 0; i < 2; i++) {
74                 plat.person1TakePhoto();
75             }
76         },"张三").start();
77         new Thread(()->{
78             for (int i = 0; i < 2; i++) {
79                 plat.person2TakePhoto();
80             }
81         },"李四").start();
82         new Thread(()->{
83             for (int i = 0; i < 2; i++) {
84                 plat.person3TakePhoto();
85             }
86         },"王五").start();
87     }
88 }

输出结果:

张三拍了1张照片
李四拍了1张照片
李四拍了2张照片
李四拍了3张照片
王五拍了1张照片
王五拍了2张照片
王五拍了3张照片
王五拍了4张照片
王五拍了5张照片
张三拍了1张照片
李四拍了1张照片
李四拍了2张照片
李四拍了3张照片
王五拍了1张照片
王五拍了2张照片
王五拍了3张照片
王五拍了4张照片
王五拍了5张照片
View Code

猜你喜欢

转载自www.cnblogs.com/xdcat/p/12960629.html