Lock的使用
本质上Lock仅仅是一个 接口,可以通过显式定义同步锁对象来实现同步,能够提供比synchronized更广泛的锁定操作,并支持 多个相关的Condition对象。
-void lock() : 尝试获取锁,获取成功则返回,否则阻塞当前线程;
—void lockInterruptibly() throws InterruptedException;尝试获取锁,线程在成功获取锁之前被中断,则 放弃获取锁,抛出异常;
—boolean tryLock();尝试获取锁,获取锁成功则返回true,否则返回false;
—boolean tryLock(long time, TimeUnit unit)尝试获取锁,若在规定时间内获取到锁,则返回true,否则 返回false,未获取锁之前被中断,则抛出异常;
-void unlock() : 释放锁
-Condition newConditio() : 返回当前锁的条件变量,通过条件变量可以实现类似notify和wait的功能,一个锁可以有多个条件变量。
Lock有三个实现类,一个是ReentrantLock,另两个是ReentrantReadWriteLock类中的两个静态内部类 ReadLock和WriteLock。
使用方法:多线程下访问(互斥)共享资源时, 访问前加锁,访问结束以后解锁,解锁的操作推荐放入 finally块中。
private final ReentrantLock lock=new ReentrantLock(); //构建锁对象;
在具体方法中lock.lock() try{}finally{lock.unlock}
Condition接口
Condition是j.u.c包下提供的一个接口。可以翻译成 条件对象,其作用是线程先等待,当外部满足某一 条件时,在通过条件对象唤醒等待的线程。
void await() throws InterruptedException;让线程进入等待,如果其他线程调用同一Condition对象的 notify/notifyAll,那么等待的线程可能被唤醒。释放掉锁
void signal();唤醒等待的线程
void signalAll();唤醒所有线程
使用Condition的特殊点
-当调用condition.await()阻塞线程时会自动释放锁,不管调用了多少次lock.lock(),这是阻塞在lock.lock()方法上线程则可以获取锁;
-当调用condition.signal()唤醒线程时会继续上次阻塞的位置继续执行,默认会自动获取锁(注意和阻塞时获取锁的次数一致);