package com.wangan.logistic; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class WanganReentrantLockService { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); private void await() { try { lock.lock(); System.out.println(Thread.currentThread().getName() + "线程获得了lock"); System.out.println(Thread.currentThread().getName() + "线程await,暂交出锁,并进入等待队列"); condition.await(); System.out.println(Thread.currentThread().getName() + "线程被从await唤醒,获得之前交出的锁并继续执行"); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); System.out.println(Thread.currentThread().getName() + "线程释放了lock"); } } private void signal() { try { lock.lock(); System.out.println(Thread.currentThread().getName() + "线程获得了lock"); condition.signal(); System.out.println(Thread.currentThread().getName() + "线程发出signal,非公平唤醒等待队列中的其他线程"); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); System.out.println(Thread.currentThread().getName() + "线程释放了锁"); } } public static void main(String[] args) { WanganReentrantLockService service = new WanganReentrantLockService(); new Thread(new Runnable() { @Override public void run() { /* * 这块可以模拟一下如果这个线程比main线程跑的慢,会发生什么 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } */ service.await(); } }).start(); try { Thread.sleep(3000); //防止main线程跑得比Thread-0还快 } catch (InterruptedException e) { e.printStackTrace(); } service.signal(); } }
控制台输出:
Thread-0线程获得了lock Thread-0线程await,暂交出锁,并进入等待队列 main线程获得了lock main线程发出signal,非公平唤醒等待队列中的其他线程 main线程释放了锁 Thread-0线程被从await唤醒,获得之前交出的锁并继续执行 Thread-0线程释放了lock
程序进程执行完毕,进程正常结束。
如果把代码中注释掉的部分放开,故意让new出来的线程跑的比main线程慢的话,控制台输出:
main线程获得了lock main线程发出signal,非公平唤醒等待队列中的其他线程 main线程释放了锁 Thread-0线程获得了lock Thread-0线程await,暂交出锁,并进入等待队列
此时由于最后Thread-0线程一直处于await没有其他线程去唤醒了,程序进程会一直阻塞中。
最后,看一下lock.newCondition()的说明:
Condition java.util.concurrent.locks.Lock.newCondition()
Returns a new Condition instance that is bound to this Lock instance.
Before waiting on the condition the lock must be held by thecurrent thread.
A call to Condition.await() will atomically release the lockbefore waiting
and re-acquire the lock before the wait returns.
newCondition()会返回一个与当前lock绑定的Condition实例。当前线程必须先获得lock,才能condition.await()。
一旦调用condition.await(),当前线程会释放lock然后进入waiting(此时lock会被其他线程获得),并且在从wait返回之前会重新申请锁(持有锁的线程signal通知其他wait线程重新申请锁,而后该持锁线程会释放锁)。