使用读/写锁的方法和步骤:
创建一个ReentrantReadWriteLock对象
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
分别获得读取锁和写入锁
private Lock readLock = rwl.readLock();
private Lock writeLock = rwl.writeLock();
对所有的读取操作加锁
public void getTotalBalance(){
readLock.lock();
try {
} catch (Exception e) {
// TODO: handle exception
}finally{
readLock.unlock();
}
}
对所有的写操作加锁
public void transfer(){
writeLock.lock();
try {
} catch (Exception e) {
// TODO: handle exception
}finally{
writeLock.unlock();
}
}
实例体会
public class ReentrantReadWriteLockDemo {
public static void main(String[] args){
final CountUseReadWriteLock crwl = new CountUseReadWriteLock();
for (int i = 0; i < 3; i++) {
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
crwl.get();
}
}.start();
}
for (int i = 0; i < 3; i++) {
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
crwl.put();
}
}.start();
}
}
}
class CountUseReadWriteLock{
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public void get() {
// TODO Auto-generated method stub
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"read begin");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+"read over");
} catch (Exception e) {
// TODO: handle exception
}finally{
rwl.readLock().unlock();
}
}
public void put() {
// TODO Auto-generated method stub
rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"write begin");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+"write over");
} catch (Exception e) {
// TODO: handle exception
}finally{
rwl.writeLock().unlock();
}
}
}
运行结果:
从结果中可以看出,读线程是可以并发的执行,而写操作是互斥的,按照顺序来执行的。
总结读写锁的机制
* 1.读-读不互斥,比方当前有10个线程去读一个资源,这10个线程可以并发的读,而不会堵塞
* 2.读-写互斥,当前有写的线程的时候,所有的读线程就会堵塞,相反,有读线程的时候,所有的写线程也会堵塞
* 3.写-写互斥,写线程都是互斥的,如果两个线程去写,A线程先拿到锁就先写,B线程就会堵塞知道A线程释放锁