码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程编程4--ReentrantReadWriteLock的使用(读写锁)

时间:2016-05-13 01:12:59      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

    类ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务。这样做虽然保证了实例变量的线程安全性,但效率却是非常低下的。所以在JDK中提供了一种读写锁ReentrantReadWriteLock类,使用它可以加快运行效率,在某些不需要操作实例变量的方法中,完全可以使用读写锁ReentrantReadWriteLock来提升该方法的代码运行速度。
    读写锁表示也有两个锁,一个是读操作相关的锁,也称为共享锁;另一个是写操作相关的锁,也叫排他锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。在没有线程Thread进行写人操作时,进行读取操作的多个Thread都可以获取读锁,而进行写人操作的Thread只有在获取写锁后才能进行写人操作。即多个Thread可以同时进行读取操作,但是同一时刻只允许一个Thread进行写人操作。

1、读读共享

public class Service {
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
        try {
            lock.readLock().lock();
            System.out.println("获得读锁:" +Thread.currentThread().getName()
                    +" " +System.currentTimeMillis());
        } finally {
            lock.readLock().unlock();
        }
    }
}
两个自定义线程
public class MyThread1 extends Thread {
    private Service service;

    public MyThread1(Service service) {
        this.service = service;
    }
    @Override
    public void run() {
        service.read();
    }
}
public class MyThread2 extends Thread{
    private Service service;

    public MyThread2(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        service.read();
    }
}
public class Run {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        MyThread1 a = new MyThread1(service);
        a.setName("AA");
        a.start();

        MyThread2 b = new MyThread2(service);
        b.setName("BB");
        b.start();
    }
}
获得读锁:AA 1462676138838
获得读锁:BB 1462676138841
    从控制台中打印的时间来看,两个线程几乎同时进人lock方法后面的代码。说明在此使用了lock.readLock()读锁可以提高程序运行效率,.允许多个线程同时执行locks方法后面的代码。

2、写写互斥

public class Service {
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    
    public void write() {
        try {
            lock.writeLock().lock();
            System.out.println("获得写锁:" +Thread.currentThread().getName()
                    +" " +System.currentTimeMillis());
        } finally {
            lock.writeLock().unlock();
        }
    }
}
上面自定义的线程将read方法改为为write方法。Run类不变,结果如下
获得写锁:BB 1462676627323
获得写锁:AA 1462676627323
使用写锁lock.writeLock()的效果就是同一时间只允许一个线程执行lock方法后面的代码
3、读写/写读互斥

public class Service {
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
        try {
            lock.readLock().lock();
            System.out.println("获得读锁:" +Thread.currentThread().getName()
                    +" " +System.currentTimeMillis());
            Thread.sleep(3000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
    }

    public void write() {
        try {
            lock.writeLock().lock();
            System.out.println("获得写锁:" +Thread.currentThread().getName()
                    +" " +System.currentTimeMillis());
            Thread.sleep(3000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }
}
自定义的线程MyThread1里的run为read方法,MyThread2里的run方法为write.
获得写锁:BB 1462677688372
获得读锁:AA 1462677691372
说明‘“读写”是互斥的

    “读写”“、”写读“、”写写“都是互斥的;而”读读“是异步的,非互斥的

Java多线程编程4--ReentrantReadWriteLock的使用(读写锁)

标签:

原文地址:http://blog.csdn.net/ochangwen/article/details/51344626

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!