Java Lock与Condition的理解 ReentrantLock锁的简单使用

匿名 (未验证) 提交于 2019-12-02 21:53:52

Lock

ReentrantLock 是我们常用的锁,日常我们都只使用了其中一部分功能如下:

        ReentrantLock lock = new ReentrantLock();         lock.lock();         try {             ....          } finally {             lock.unlock();         }

实际上Java提供的LinkedBlockingQueue类就是基于ReentrantLock与Condition结合使用的,这是很经典的生产与消费场景,里面有两个锁putLock与takeLock锁。解决问题:取元素时takeLock已经获取到锁了,但是由于列队是空的,使用notEmpty.await()使当前线程处理等待状态,这时如果有新的线程调用take方法时,新的线程也能获取到锁,也会继续等待,当put元素后, notEmpty.signal()发送信号,会唤醒其中一个等待线程。
使用condition可以使线程交互变的更加灵活,ReentrantLock可以定义公平锁与非公平锁,公平锁可以保证线程访问顺序,非公平锁不一定保证线程访问顺序,默认为非公平锁。

//每次取完之后使用自唤醒方法使其它等待线程,多了一重信息通知,取完之后会调用notFull方法唤醒正在等写入的方法 public E take() throws InterruptedException {         E x;         int c = -1;         final AtomicInteger count = this.count;         final ReentrantLock takeLock = this.takeLock;         takeLock.lockInterruptibly();//获取锁         try {             while (count.get() == 0) {//如果当前元素为0线程等待                 notEmpty.await();             }             x = dequeue();//取一个元素             c = count.getAndDecrement();//总数减1             if (c > 1)//如果有元素 继续唤醒一个等待线程                 notEmpty.signal();         } finally {             takeLock.unlock();         }         if (c == capacity)             signalNotFull();         return x;     }
public void put(E e) throws InterruptedException {     if (e == null) throw new NullPointerException();     int c = -1;     Node<E> node = new Node<E>(e);     final ReentrantLock putLock = this.putLock;     final AtomicInteger count = this.count;     putLock.lockInterruptibly();     try {          while (count.get() == capacity) {//列队满,等列队有空间             notFull.await();         }         enqueue(node);//插入元素         c = count.getAndIncrement();//总数加1         if (c + 1 < capacity)//列队未满,唤醒正在等待的线程             notFull.signal();     } finally {         putLock.unlock();     }     if (c == 0)//通知正在等待取元素的线程         signalNotEmpty(); }
synchronized (writeLock) {     while (runThreadNum >= 5) {         try {             System.out.println("threadNum:" + runThreadNum);             writeLock.wait();         } catch (InterruptedException e) {             e.printStackTrace();         }     } }
 import java.util.Date; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock;  /**  * Created by zengrenyuan on 18/6/11.  */ public class TestLock {      public static final int maxNum = 1;     private final ReentrantLock lock = new ReentrantLock();     private final Condition notFull = lock.newCondition();     private final Condition notEmpty = lock.newCondition();     private AtomicInteger count = new AtomicInteger(0);      public static void main(String[] args) throws InterruptedException {         final TestLock testLock = new TestLock();         testLock.putThread("线程1");         testLock.putThread("线程2");         testLock.putThread("线程3");         testLock.putThread("线程4");         testLock.putThread("线程5");         testLock.readThread("读线程");     }      public void readThread(String name) {         Thread thread = new Thread(new Runnable() {             @Override             public void run() {                 while (true) {                     try {                         read();                     } catch (InterruptedException e) {                         e.printStackTrace();                     }                 }             }         });         thread.setName(name);         thread.start();       }      public void read() throws InterruptedException {         lock.lock();         try {             while (count.get() == 0) {                 notEmpty.await();             }             System.out.println("read:" + count.decrementAndGet());             notFull.signal();         } finally {             lock.unlock();         }     }       public void putThread(String name) {         Thread thread = new Thread(new Runnable() {             @Override             public void run() {                 try {                     print();                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         });         thread.setName(name);         thread.start();     }      public void print() throws InterruptedException {         lock.lock();         try {             System.out.println("threadName" + Thread.currentThread().getName());             while (count.get() == maxNum) {                 notFull.await();             }             System.out.println("put:" + count.getAndIncrement() + " threadName" + Thread.currentThread().getName());             System.out.println(MiscUtils.formatDate(new Date(), MiscUtils.STANDARDPATTERN));             notEmpty.signal();         } finally {             lock.unlock();         }     }   }

https://www.jianshu.com/p/eb112b25b848
http://jszx-jxpt.cuit.edu.cn/JavaAPI/java/util/concurrent/locks/Condition.html
http://jszx-jxpt.cuit.edu.cn/JavaAPI/java/util/concurrent/locks/Lock.html
https://www.jianshu.com/p/71ad3c675cbe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!