您的位置:首页 > 编程语言 > Java开发

java锁——ReentrantLock

2016-03-27 14:05 477 查看

java.util.concurrent.locks.Lock

Lock接口与synchronized的区别:
1.Lock接口允许分离读和写操作,允许多个读线程和只有一个写线程
2.在高并发的环境下,Lock性能更好
3.支持更灵活的同步代码块结构,可以让锁的获取和释放不在同一个代码块

使用Lock接口的一般模式:
private final Lock lock = new ReentrantLock();

public void a() {
//获取锁
lock.lock();
//...执行需要同步的操作
//释放锁
lock.unlock();
}

在使用Lock的时候必须记住释放锁,把lock.unlock()放到finally中是不错的选择

Lock接口提供了另一个tryLock()方法来获取锁
线程如果不能通过tryLock()获取锁,tryLock()会立即返回,不会将线程进入休眠状态
应该注意的是当tryLock()方法返回false的时候程序不应该再执行临界区代码

读写锁:ReentrantReadWriteLock

是Lock的一个实现类,允许分离读和写操作,允许多个读线程和只有一个写线程
一般用法:
//读写锁
private ReadWriteLock lock = new ReentrantReadWriteLock();
//读操作
public void read() {
lock.readLock().lock();
//进行读的操作
lock.readLock().unlock();
}
//写操作
public void write() {
lock.writeLock().lock();
//进行写的操作
lock.writeLock().unlock();
}

线程进入读锁的前提条件:
    没有其他线程的写锁,
    没有写请求或者写请求的线程是持有该读锁的线程
线程进入写锁的前提条件:
    没有其他线程的读锁
    没有其他线程的写锁

wait()和notify()模式的替代品——await()和signalAll()

在生产者消费者模式中使用了wait()和notify(),现在用Lock接口来实现
一个Lock接口可能关联了一个或者多个条件,这些条件用Condition接口来抽象
Condition接口提供了线程的挂起和唤醒机制

Condition使用实例代码
//创建锁
private Lock lock = new ReentrantLock();
//创建关联条件
private Condition isFull = lock.newCondition();
private Condition isEmpty = lock.newCondition();
private int size = 2;

void get() {
//获取锁
lock.lock();
try {
//等待满足条件并接到唤醒通知
while (size == 0) {
isEmpty.await();
}
System.out.println("doGet when size == " + (size--));
isEmpty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}

void set() {
//获取锁
lock.lock();
try {
//等待满足条件并接到唤醒通知
while (size == 2) {
isFull.await();
}
System.out.println("doSet when size == " + (size++));
isFull.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}

在调用condition的时候必须先获取congdition绑定的锁,所以condition的执行代码必须在lock()和unlock()之间
和wait()一样,condition.await()也会释放其绑定的锁


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ReentraintLock Lock java