ReadWriteLock
提供两个基础方法,readLock获取读机制锁,writeLock获取写机制锁。
ReentrantReadWriteLock
接口ReadWriteLock的具体实现,特点:基于读锁时,其他线程可以进行读操作,基于写锁时,其他线程读、写操作都禁止。
2、使用案例读写分离模式
通过读写锁机制,分别向数据容器Map中写入数据和读取数据,以此验证读写锁机制。
- public class LockAPI03 {
- public static void main(String[] args) throws Exception {
- DataMap dataMap = new DataMap() ;
- Thread read = new Thread(new GetRun(dataMap)) ;
- Thread write = new Thread(new PutRun(dataMap)) ;
- write.start();
- Thread.sleep(2000);
- read.start();
- }
- }
- class GetRun implements Runnable {
- private DataMap dataMap ;
- public GetRun (DataMap dataMap){
- this.dataMap = dataMap ;
- }
- @Override
- public void run() {
- System.out.println("GetRun:"+dataMap.get("myKey"));
- }
- }
- class PutRun implements Runnable {
- private DataMap dataMap ;
- public PutRun (DataMap dataMap){
- this.dataMap = dataMap ;
- }
- @Override
- public void run() {
- dataMap.put("myKey","myValue");
- }
- }
- class DataMap {
- Map dataMap = new HashMap<>() ;
- ReadWriteLock rwLock = new ReentrantReadWriteLock() ;
- Lock readLock = rwLock.readLock() ;
- Lock writeLock = rwLock.writeLock() ;
- // 读取数据
- public String get (String key){
- readLock.lock();
- try{
- return dataMap.get(key) ;
- } finally {
- readLock.unlock();
- }
- }
- // 写入数据
- public void put (String key,String value){
- writeLock.lock();
- try{
- dataMap.put(key,value) ;
- System.out.println("执行写入结束...");
- Thread.sleep(10000);
- } catch (Exception e) {
- System.out.println("Exception...");
- } finally {
- writeLock.unlock();
- }
- }
- }
说明:当put方法一直在睡眠状态时,因为写锁的排它性质,所以读方法是无法执行的。
三、基础工具类LockSupport简介
LockSupprot定义一组公共静态方法,这些方法提供最基本的线程阻塞和唤醒功
能。
基础方法
park():当前线程阻塞,当前线程被中断或调用unpark方法,park()方法中返回;
park(Object blocker):功能同park(),传入Object对象,记录导致线程阻塞的阻塞对象,方便问题排查;
parkNanos(long nanos):指定时间nanos内阻塞当前线程,超时返回;
unpark(Thread thread):唤醒指定处于阻塞状态的线程;
代码案例
该流程在购物APP上非常常见,当你准备支付时放弃,会有一个支付失效,在支付失效期内可以随时回来支付,过期后需要重新选取支付商品。
- public class LockAPI04 {
- public static void main(String[] args) throws Exception {
- OrderPay orderPay = new OrderPay("UnPaid") ;
- Thread orderThread = new Thread(orderPay) ;
- orderThread.start();
- Thread.sleep(3000);
- orderPay.changeState("Pay");
- LockSupport.unpark(orderThread);
- }
- }
- class OrderPay implements Runnable {
- // 支付状态
- private String orderState ;
- public OrderPay (String orderState){
- this.orderState = orderState ;
- }
- public synchronized void changeState (String orderState){
- this.orderState = orderState ;
- }
- @Override
- public void run() {
- if (orderState.equals("UnPaid")){
- System.out.println("订单待支付..."+orderState);
- LockSupport.park(orderState);
- }
- System.out.println("orderState="+orderState);
- System.out.println("订单准备发货...");
- }
- }
这里基于LockSupport中park和unpark控制线程状态,实现的等待通知机制。