lock接口及其实现-挂起唤醒-和synchronized的区别-读写锁

# lock接口 ![image.png](https://cos.easydoc.net/31477061/files/kmbirlq6.png) ## lock接口方法及测试 ![image.png](https://cos.easydoc.net/31477061/files/kmbitb9p.png) ``` package smm.test.app.multiplesystems.lifter1; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class test { //公平锁 //static Lock lock = new ReentrantLock(true); //非公平锁 static Lock lock = new ReentrantLock(); public static void main(String args[]) throws InterruptedException { //主线程 拿到锁 lock.lock(); Thread th = new Thread(new Runnable() { @Override public void run() { //子线程 获取锁(不死不休)== synchronized /* System.out.println("begain to get lock..."); lock.lock(); System.out.println("interrupted...");*/ //子线程 获取锁(浅尝辄止) /* boolean result = lock.tryLock(); System.out.println("是否获得到锁:" +result);*/ //子线程 获取锁(点到为止) /* try { boolean result1 = lock.tryLock(5, TimeUnit.SECONDS); System.out.println("是否获得到锁:" +result1); } catch (InterruptedException e) { e.printStackTrace(); }*/ //子线程 获取锁(任人摆布) 可中断的锁 th.interrupt(); /* try { System.out.println("start to get lock Interruptibly"); lock.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("dad asked me to stop..."); }*/ } }); th.start(); Thread.sleep(3000); System.out.println(th.getState()); Thread.sleep(5000); th.interrupt(); Thread.sleep(100000L); lock.unlock(); } } ``` ## lock的挂起和唤醒,类似Synchronized ``` package com.study.lock; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Demo3_Condition { private static Lock lock = new ReentrantLock(); static Condition condition = lock.newCondition(); //相当于Synchronized里面的WaitSet 等待池 死锁方式和Synchronized一样,不可以先唤醒,会死锁 public static void main(String args[]){ Thread th = new Thread(){ @Override public void run() { super.run(); lock.lock(); try { condition.await(); //await 不仅将线程挂起,还会释放锁 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }; th.start(); lock.lock(); try { condition.signal(); }finally { lock.unlock(); } } } ``` ## Synchronized / lock (优点-缺点) ![image.png](https://cos.easydoc.net/31477061/files/kmbkqgel.png) ## hashmap是线程不安全的使用读写锁优化 ``` package com.study.lock; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; // 将hashmap 改造一个并发安全的 // 这是ReentrantReadWriteLock注释中给出的一个示例 public class Demo7_Map { private HashMap<Object, Object> map = new HashMap<>(); ReadWriteLock rwLock = new ReentrantReadWriteLock(); public Object get(Object key){ rwLock.readLock().lock(); try { return map.get(key); }finally { rwLock.readLock().unlock(); } } public void put(Object key,Object value){ rwLock.writeLock().lock(); try { map.put(key, value); }finally { rwLock.writeLock().unlock(); } } } ``` ## 锁降级 读写互斥, 特例(必须是同一个线程):当t1线程加了写锁,在写锁里在加上读锁,在释放写锁,就会变成锁降级成读锁(不释放锁)。 好处:当修改并查询时,先修改加写锁,如果不加读锁就释放锁,可能会被其他线程抢到锁,再查询时就不是刚修改的内容了,可能会被其他线程抢到锁