Synchronized与Lock(周阳视频学习记录)

1、synchronized与lock的区别

1.1 原始组成

synchronized是属于JVM层面的关键字

Lock是具体类(java.util.concurrent.locks.Lock)是api层面的

1.2 使用方法

synchronized不需要用户去手动释放锁,当synchronized代码执行完毕后系统会自动释放锁

Lock(本文都用ReentrantLock举例),则需要用户去手动释放锁,若没有释放锁,就有可能导致死锁出现。通过lock()加锁、unlock()释放锁配合try / finally使用

1.3 等待是否可中断

synchronized不可中断,除非抛出异常或正常执行完毕

ReentrantLock可中断:

  1. 设置超时方法tryLock(long timeout, TimeUnit unit)
  2. lockInterruptibly()放代码块中,调用interrupt()方法可中断

1.4 加锁是否公平 

synchronized非公平锁

ReentrantLock两者都可以,默认非公平,构造方法可以传入boolean值,true为公平,false为非公平

1.5 锁绑定多个条件Condition

 synchronized不能

ReetrantLock用来实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

案例说明:

/**
 * 测试锁绑定多个条件Condition
 * 案例:多线程之间按顺序调用,实现 A -> B -> C 三个线程启动,要求如下:
 * A打印5次,B打印10次,C打印15次
 * 这样循环10轮
 */
public class SyncAndReentrantLockDemo {
    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                shareResource.printInfo(5);
            }, "A").start();
            new Thread(() -> {
                shareResource.printInfo(10);
            }, "B").start();
            new Thread(() -> {
                shareResource.printInfo(15);
            }, "C").start();
        }

    }
}

/**
 * 多线程调用资源类
 */
class ShareResource {
    /**
     * 定义A:1,B:2,C:3
     */
    private int number = 1;
    private Lock lock = new ReentrantLock();
    private final Condition c1 = lock.newCondition();
    private final Condition c2 = lock.newCondition();
    private final Condition c3 = lock.newCondition();

    private static Map<Integer, ConditionData> intToCondMap = new ConcurrentHashMap<>();

    /**
     * 这里只在主线程执行一次,相当于一个单线程可以不使用ConcurrentHashMap
     */
    public ShareResource() {
        intToCondMap.put(5, new ConditionData(1, c1, 2, c2));
        intToCondMap.put(10, new ConditionData(2, c2, 3, c3));
        intToCondMap.put(15, new ConditionData(3, c3, 1, c1));
    }

    public void printInfo(final int n) {
        lock.lock();
        try {
            // 1、判断
            ConditionData conditionData = intToCondMap.get(n);
            while (number != conditionData.getCurNumber()) {
                conditionData.getCurCond().await();
            }
            // 2、执行
            printCount(n);
            // 3、通知
            number = conditionData.getNextNumber();
            conditionData.getNextCond().signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private void printCount(int n) {
        for (int i = 1; i <= n; i++) {
            System.out.println(Thread.currentThread().getName() + "\t" + i);
        }
    }
}

@AllArgsConstructor
@Getter
class ConditionData {
    private int curNumber;
    private Condition curCond;
    private int nextNumber;
    private Condition nextCond;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值