for update什么时候释放锁_Java并发编程笔记-显示锁Lock

Java提供了synchronized关键字为什么还要提供Lock接口?

synchronized是Java语言特性,使用简单,我们无需关注加锁与释放的过程,synchronized锁是非公平锁,可重入但不理会中断;Lock接口本质是一个Java类,加锁与释放需要我们手动控制,使用比较灵活,获取锁时可以选择使用公平锁还是非公平锁,可以设置获取锁的等待超时时长,可重入,可以中断获取锁的线程。JDK1.6之后,经过JVM团队对synchronized关键字的优化,二者在性能上没有太大差距,JDK 1.8里ConcurrentHashMap的实现上看,JVM对自己的优化还是有自信的。

Lock接口

c470658e7fa6a52a04baab24bbd058cc.png
  1. lock():获取锁,如果锁不可用,则线程进入阻塞状态,直到已获取锁。
  2. lockInterruptibly():获取锁,如果锁可用则线程继续执行;如果锁不可用,则线程进入阻塞状态,支持当前线程和锁获取中断。
  3. tryLock():尝试获取锁,如果无法获取锁标记,立即返回false;如果获取了锁标记,立即返回true。
  4. tryLock(long time, TimeUnit unit):如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。
  5. unlock():释放锁,在等待条件前,锁必须由当前线程保持。
  6. Condition newCondition():返回当前Lock 实例的Condition实例。

Lock接口标准使用模板:

lock.lock();try { //TODO 业务逻辑} finally { lock.unlock();}

Lock实现之ReentrantLock基本使用

public class ReentrantLockDemo { private final Lock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); private int count; public void add() { lock.lock(); try { condition.await(); this.count++; } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void signalAdd() { lock.lock(); try { condition.signalAll(); } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { final ReentrantLockDemo reentrantLockDemo = new ReentrantLockDemo(); for (int i = 0; i < 10; i++) { new Thread(() -> reentrantLockDemo.add()).start(); } Thread.sleep(3000); System.out.println("开始:" + reentrantLockDemo.count); reentrantLockDemo.signalAdd(); Thread.sleep(3000); System.out.println("结束:" + reentrantLockDemo.count); }}
c7de347358c44c150fa0e1e19e616222.png

ReadWriteLock接口

a89baeb543b024a53e4397b5753fbaf8.png
  1. readLock():读的时候返回读锁,读锁共享,允许多个线程同时获取锁,获取读锁后不允许写
  2. writeLock():写的时候返回写锁,写锁独占,不允许读和写

ReadWriteLock实现之ReentrantReadWriteLock基本使用

public class ReentrantReadWriteLockDemo { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Lock readLock = lock.readLock(); private final Lock writeLock = lock.writeLock(); private int count; public void writeCount(){ writeLock.lock(); try { Thread.sleep(100); count++; System.out.println(Thread.currentThread().getName() + ":setCount = " + count); } catch (InterruptedException e) { e.printStackTrace(); } finally { writeLock.unlock(); } } public void readCount() { readLock.lock(); try { System.out.println(Thread.currentThread().getName() + ":getCount = " + count); } finally { readLock.unlock(); } } public static void main(String[] args) throws InterruptedException { final ReentrantReadWriteLockDemo reentrantReadWriteLockDemo = new ReentrantReadWriteLockDemo(); for (int i = 0; i < 10; i++) { new Thread(() -> { reentrantReadWriteLockDemo.readCount(); }).start(); } for (int i = 0; i < 3; i++) { new Thread(() -> { reentrantReadWriteLockDemo.writeCount(); }).start(); } }}
a66bb34ca8d2852a7f4c293b9a2eba0a.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值