java concurrent 源码_Java 的 java.util.concurrent.locks 源码分析

包含接口和类

java.util.concurrent.locks 包下包含如下接口和类

d39167eb70cbacf49fa3c1ada05f5f49.png

jdk 截图如下:

d331d1c171425d951c744c624b99daf4.png

为什么使用 Lock,Lock 和 synchronized 的区别

类别

synchronized

Lock

存在层次

Java 的关键字,在 jvm 层面上

是一个类

锁的释放

1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm 会让线程释放锁

在 finally 中必须释放锁,不然容易造成线程死锁

锁的获取

假设 A 线程获得锁,B 线程等待。如果 A 线程阻塞,B 线程会一直等待

分情况而定,Lock 有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待

锁状态

无法判断

可以判断

锁类型

可重入 不可中断 非公平

可重入 可判断 可公平(两者皆可)

性能

少量同步

大量同步

Lock 接口

package java.util.concurrent.locks;

import java.util.concurrent.TimeUnit;

public interface Lock {

//获取锁

void lock();

//获得锁除非当前线程被中断

void lockInterruptibly() throws InterruptedException;

//当在调用时刻时锁有效,则获得锁

boolean tryLock();

//在指定时间内获得锁,并且在该时间内线程没有被中断

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

//释放锁

void unlock();

//返回该锁实例的一个Condition,用于线程同步

Condition newCondition();

}

Condition 接口

任一个 Java 对象,都拥有一组监视器方法(定义在 java.lang.Object 类上),主要包括 wait()、wait(long)、notify()、notifyAll() 方法,这些方法与 synchronized 关键字配合,可以实现等待 / 通知模式。Condition 接口也提供了类似 Object 的监视器方法,与 Lock 配合可以实现等待 / 通知模式,但两者的使用方式以功能特性有一定的区别。Object 的监视器方法与 Condition 接口对比如下:

对比项

Object 监视器方法

Condition

前置条件

获取对象的监视器锁

调用 Lock.lock()获取锁,调用 Lock.newCondition() 获取 Condition 对象

调用方法

直接调用 如:object.wait()

直接调用 如:condition.await()

等待队列个数

一个

多个

当前线程释放锁并进入等待队列

支持

支持

当前线程释放锁并进入等待队列,在等待状态中不响应中断

不支持

支持

当前线程释放锁并进入超时等待状态

支持

支持

当前线程释放锁并进入等待状态到将来的某个时间

不支持

支持

唤醒等待队列中的一个线程

支持

支持

唤醒等待队列中的全部线程

支持

支持

源码

package java.util.concurrent.locks;

import java.util.concurrent.TimeUnit;

import java.util.Date;

/**

* 使用方法

* class BoundedBuffer {

* final Lock lock = new ReentrantLock();

* final Condition notFull = lock.newCondition();

* final Condition notEmpty = lock.newCondition();

*

* final Object[] items = new Object[100];

* int putptr, takeptr, count;

*

* public void put(Object x) throws InterruptedException {

* lock.lock();

* try {

* while (count == items.length)

* notFull.await();

* items[putptr] = x;

* if (++putptr == items.length) putptr = 0;

* ++count;

* notEmpty.signal();

* } finally {

* lock.unlock();

* }

* }

*

* public Object take() throws InterruptedException {

* lock.lock();

* try {

* while (count == 0)

* notEmpty.await();

* Object x = items[takeptr];

* if (++takeptr == items.length) takeptr = 0;

* --count;

* notFull.signal();

* return x;

* } finally {

* lock.unlock();

* }

* }

* }

*

*

* condition调用await方法后,condition的锁是释放了的,condition调用signal或者signalAll后,再重新获得锁

*

*/

public interface Condition {

//当前线程进入等待状态直到被通知(signal)或中断。

void await() throws InterruptedException;

//当前线程进入等待状态直到被通知,该方法不响应中断。

void awaitUninterruptibly();

//当前线程进入等待状态直到被通知、中断或者超时,返回值表示剩余超时时间。

long awaitNanos(long nanosTimeout) throws InterruptedException;

//当前线程进入等待状态直到被通知、中断或者到某个时间。如果没有到指定时间就被通知,方法返回true,否则,表示到了指定时间,返回false。

boolean awaitUntil(Date deadline) throws InterruptedException;

//唤醒一个等待在Condition上的线程,该线程从等待方法返回前必须获得与Condition相关联的锁。

void signal()

//唤醒所有等待在Condition上的线程,能够从等待方法返回的线程必须获得与Condition相关联的锁。

void signalAll();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值