Java多线程锁--lock

死锁

死锁产生的条件

  • 互斥:共享资源只能同时被一个线程占用
  • 占有且等待:eg:拿到worker锁,不释放的同时去申请money锁
  • 不可抢占:线程Thread1拿到对象锁x后,其他线程无法强行抢占x锁。
  • 循环等待:线程T1拿到了资源X的锁,去申请Y的锁。线程T2拿到了资源Y的锁,去申请X的锁。

Lock-JDK1.5-基于Java语言层面实现的线程"锁"

产生背景:synchronized死锁

破坏不可抢占:

  • 能够响应中断
  • 支持超时
  • 非阻塞式获取锁

Lock接口下的三个重要方法

  • 响应中断 void lockInterruptibly();
  • 支持超时 boolean tryLock(long time, TimeUnit unit)
  • 非阻塞式获取锁 线程若获取不到锁,线程直接退出 boolean tryLock();

Lock体系使用的格式

Lock lock=new ReentrantLock();
try {
    // 加锁
    lock.lock();
}finally {
    // 解锁
    lock.unlock();
}

synchronized同步块执行完成或者遇到异常时锁会自动释放,而lock必须调用unlock()方法释放锁,因此在finally块中释放锁

Lock接口中的方法

  • void lock();   //获取锁
  • void lockInterruptibly()throws InterruptedException;//获取锁的过程相应中断
  • boolean tryLock();//非阻塞式响应中断能立即返回,获取锁返回true,反之为false
  • boolean tryLock(long time,TimeUnit unit);//超时获取锁,在超时时间内或为中断的情况下能获取锁
  • Condition newCondition();//获取与lock绑定的等待通知事件,当前线程必须先获得锁才能等待,等待会释放锁,再次获取锁才能从等待中返回

公平锁

等待时间最长的线程最先获取到锁(synchronizd无法实现公平锁)

public ReentrantLock() {  
  sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {     //传入参数为true为公平锁
  sync = fair ? new FairSync() :
 new NonfairSync();
}

公平锁每次都是从同步队列中的第一个节点获取到锁,而非公平锁则不一定,有可能刚释放的线程再次获取到锁

独占锁

synchronized,在任意一个时刻,只有一个线程可以拥有此锁

  • void acquire(int arg); 独占式获取同步状态,如果获取失败则插入同步队列进行等待
  • boolean tryAcquire(int arg); 获取锁成功返回true,否则返回false
  • boolean release(int arg); 释放同步状态,该方法会唤醒在同步队列中的下一个节点

共享锁

在同一个时刻,可以有多个线程拥有锁

  • void acquireShared(int arg) ; 共享式获取同步状态,与独占锁的区别在于同一个时刻有多个线程获取同步队列
  • boolean releaseShared(int arg); 共享释放同步状态

读写锁-共享锁的一种实现

读锁共享:多个线程可以同时拿到读锁进行访问,当写线程拿到写锁开始工作时,所有读线程全部阻塞
写锁独占:任意一个时刻,只有一个线程可以拿到写锁

读读-不互斥,读写、写写-互斥

Condition:Lock体系的线程通信方式

  • await():释放lock锁,将线程置入等待队列阻塞
  • signal():随机唤醒一个处于等待状态的线程
  • signalAll():唤醒所有等待线程

synchronized与lock的关系

  • synchronized与Lock都是对象锁,都支持可重入锁
  • Lock可以实现synchronized不具备的特性,如响应中断、支持超时、非阻塞的获取锁、公平锁、共享锁(读写锁,ReentrantReadWriteLock实现)
  • Lock体系的Condition队列可以有多个(区分于synchronized只有一个等待队列),可以进一步提高效率,减少线程阻塞与唤醒带来的开销(唤醒了不该唤醒的线程)。获取一个lock锁的condition队列:lock.newCondition() : 产生一个新的Condition队列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值