java.util.concurrent.locks包提供了锁和等待条件的接口和类, 可用于替代JDK1.5以前的同步(synchronized)和监视器机制(主要是Object类的wait(), notify(), notifyAll()方法).java
互斥锁--Lock接口及其实现类ReentrantLock并发
所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5以前, 咱们一般使用synchronized机制控制多个线程对共享资源的访问. 而如今, Lock提供了比synchronized机制更普遍的锁定操做, Lock和synchronized机制的主要区别:高并发
Java代码 性能
public class LockTest { private static Lock lock = new ReentrantLock(); public static void main(String[] args) { lock.lock(); invokeMethod(); } private static void invokeMethod() { lock.unlock(); } }
为了确保锁被释放, 一般会采用以下的代码形式:this
Java代码 线程
Lock lock = new ReentrantLock(); // 获取锁 lock.lock(); try { // access the resource protected by this lock } finally { // 释放锁 lock.unlock(); }
|--void lock(): 执行此方法时, 若是锁处于空闲状态, 当前线程将获取到锁. 相反, 若是锁已经被其余线程持有, 将禁用当前线程, 直到当前线程获取到锁.code
|--void unlock(): 执行此方法时, 当前线程将释放持有的锁. 锁只能由持有者释放, 若是线程并不持有锁, 却执行该方法, 可能致使异常的发生.orm
|--boolean tryLock(): 若是锁可用, 则获取锁, 并当即返回true, 不然返回false. 该方法和lock()的区别在于, tryLock()只是"试图"获取锁, 若是锁不可用, 不会致使当前线程被禁用, 当前线程仍然继续往下执行代码. 而lock()方法则是必定要获取到锁, 若是锁不可用, 就一直等待, 在未得到锁以前,当前线程并不继续向下执行. 一般采用以下的代码形式调用tryLock()方法:对象
Java代码 blog
Lock lock = new ReentrantLock(); if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions }
此用法可确保若是获取了锁, 则会释放锁; 若是未获取锁, 则不会试图将其释放.
条件--Condition
调用Condition对象的相关方法, 能够方便的挂起和唤醒线程. Object对象的wait(), notify(), notifyAll()方法固然也能够作到这一点, 可是Object对象的这些方法存在很不方便的地方--若是多个线程调用了obj的wait()方法而挂起, 那么咱们没法作到调用obj的notify()和notifyAll()方法唤醒其中特定的一个线程. 而Condition对象就能够作到这一点. 具体的代码请参见个人上一篇博客http://coolxing.iteye.com/blog/1236696中的解法二部分.
读写锁--ReadWriteLock接口及其实现类ReentrantReadWriteLock
ReentrantReadWriteLock中定义了2个内部类, ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock, 分别用来表明读取锁和写入锁. ReentrantReadWriteLock对象提供了readLock()和writeLock()方法, 用于获取读取锁和写入锁.
使用读写锁的一个例子:
Java代码
public class ReadWriteLockTest { private static ReadWriteLock lock = new ReentrantReadWriteLock(); private static Person person = new Person("David Beckham", true); public static void main(String[] args) { new Thread() { public void run() { while(true) { try { lock.readLock().lock(); System.out.print("name = " + person.getName()); System.out.println(", isMan = " + person.isMan()); } finally { lock.readLock().unlock(); } } }; }.start(); new Thread() { public void run() { boolean state = true; while(true) { try { lock.writeLock().lock(); if (state) { person.setName("Lady GaGa"); person.setMan(false); state = false; } else { person.setName("David Beckham"); person.setMan(true); state = true; } } finally { lock.writeLock().unlock(); } } }; }.start(); } } class Person { private String name; private boolean isMan; public Person(String name, boolean isMan) { this.name = name; this.isMan = isMan; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isMan() { return isMan; } public void setMan(boolean isMan) { this.isMan = isMan; } }
无论程序运行多久, 也不会有人妖的出现.