针对Object的wait方法void await() throws InterruptedException:当前线程进入等待状态,如果其他线程调用condition的signal或者signalAll方法并且当前线程获取Lock从await方法返回,如果在等待状态中被中断会抛出被中断异常;long awaitNanos(long nanosTimeout):当前线程进入等待状态直到被通知,中断或者超时;boolean await(long time, TimeUnit unit)throws InterruptedException:同第二种,支持自定义时间单位boolean awaitUntil(Date deadline) throws InterruptedException:当前线程进入等待状态直到被通知,中断或者到了某个时间
针对Object的notify/notifyAll方法void signal():唤醒一个等待在condition上的线程,将该线程从等待队列中转移到同步队列中,如果在同步队列中能够竞争到Lock则可以从等待方法中返回。void signalAll():与1的区别在于能够唤醒所有等待在condition上的线程
原理
https://www.jianshu.com/p/cc308d82cc71
2. 锁
用synchronized 读与读不能并行,这时可以用lock来解决。
锁创建的时候不用传东西,锁同步是指你写的同一个锁的lock()和unlock()之间的代码同时只能有一个在执行。
Lock lock = new ReentrantLock(); //可重入互斥锁
try{
lock.lock()
同步代码
}finally{
lock.unlock()
}
读写锁
ReadWriteLock
ReentrantReadWriteLock
详细规则
•
线程进入读锁的前提条件:
没有其他线程的写锁,
没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。
•
线程进入写锁的前提条件:
没有其他线程的读锁
没有其他线程的写锁
而读写锁有以下三个重要的特性:
(1)公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
(2)重进入:读锁和写锁都支持线程重进入。
(3)锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。
private ReentrantReadWriteLock lockAll = new ReentrantReadWriteLock();
private long allTasks = 0;
try {
lockAll.writeLock().lock();
allTasks++;
} finally {
lockAll.writeLock().unlock();
}
获取锁之后还要调用其它方法就要可重入锁
可中断锁
可中断锁:顾名思义,就是可以相应中断的锁。
在Java中,synchronized就不是可中断锁,而Lock是可中断锁。
如果某一线程A正在执行锁中的代码,另一线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想先处理其他事情,我们可以让它中断自己或者在别的线程中中断它,这种就是可中断锁。
在前面演示lockInterruptibly()的用法时已经体现了Lock的可中断性。
➢ Lock 接口:支持那些语义不同(重入、公平等)的锁规则,可以在非阻塞式结构的上下文(包括 hand-
over-hand 和锁重排算法)中使用这些规则。主要的实现是 ReentrantLock。
➢ ReadWriteLock 接口:以类似方式定义了一些读取者可以共享而写入者独占的锁。此包只提供了一个实
现,即 ReentrantReadWriteLock,因为它适用于大部分的标准用法上下文。但程序员可以创建自己的、
适用于非标准要求的实现。
评论区