什么是读写锁

我们知道多个线程同时读一个资源类是没有任何问题的,所以在并发的情况下,读取共享资源应该是可以同时进行的;但是,如果一个线程想要去写共享资源,就不应该再有其他线程同时对该共享资源进行读或者是写操作了。

成都创新互联是一家集网站建设,友好企业网站建设,友好品牌网站建设,网站定制,友好网站建设报价,网络营销,网络优化,友好网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

(推荐教程:java入门教程)

我们想要的是:允许多个线程同时读,但只要有一个线程在写,其他线程就必须等待。

读写锁就是这个原理,即读写锁在同一时刻可以允许多个多线程访问,但是在写线程访问的时候,所有的读线程和其他写线程都会被阻塞。读写锁实际维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得其并发性比独占式锁(排他锁)有了很大的提升。

代码示例:

public class ReadWriteLockDemo {
    public static void main(String[] args) {
        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        Book book = new Book();//创建一本书,可读可写

        //两个写手
        for (int i = 0; i < 2; i++) {
            int num = i;
            new Thread(()->{
                try {
                    readWriteLock.writeLock().lock();
                    System.out.println("写手"+num+"在写文章");
                    book.write(String.valueOf(num),UUID.randomUUID().toString().substring(0,5));
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    readWriteLock.writeLock().unlock();
                }
            },String.valueOf(i)).start();
        }

        //6个读者
        for (int i = 0; i < 6; i++) {
            int num = i;
            new Thread(()->{
                try {
                    readWriteLock.readLock().lock();
                    String word = book.read(String.valueOf(num % 2));
                    System.out.println("读者"+num+"在阅读文章..."+word);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    readWriteLock.readLock().unlock();
                }
            },String.valueOf(i)).start();
        }
    }
}
class Book{
    HashMap map = new HashMap<>();
    public void write(String key,String val){
        map.put(key, val);
    }
    public String read(String key){
        String word = map.get(key);
        return word;
    }
}

输出结果:

"C:\\Program Files\\Java\\jdk1.8.0_144\\bin\\java.exe" "-javaagent:F:\\MyDir\\IDEA\\IDEA2018\\IntelliJ IDEA 2018.2.4\\lib\\idea_rt.jar=54141:F:\\MyDir\\IDEA\\IDEA2018\\IntelliJ IDEA 2018.2.4\\bin" -Dfile.encoding=UTF-8 -classpath "C:\\Program Files\\Java\\jdk1.8.0_144\\jre\\lib\\charsets.jar;C:\\Program Files\\Java\\jdk1.8.0_144\\jre\\lib\\ext\\nashorn.jar;C:\\Program Files\\Java\\jdk1.8.0_144\\jre\\lib\\rt.jar;E:\\idea_workplace\\javaBase\\target\\classes"
写手0在写文章
写手1在写文章
读者0在阅读文章...6b021
读者1在阅读文章...220e4
读者2在阅读文章...6b021
读者4在阅读文章...6b021
读者3在阅读文章...220e4
读者5在阅读文章...220e4

Process finished with exit code 0

读写锁的效率

(视频教程推荐:java视频教程)

读写锁是否会提高使用互斥锁的性能取决于数据被读取的频率与被修改的频率,读取和写入操作的持续时间以及数据的争用 ,尝试同时读取或写入数据的线程数。

例如最初填充数据的集合,然后经常被修改的频繁的搜索(例如某种目录)是使用读写锁的理想候选。 然而,如果更新变得频繁,那么数据的大部分时间将被专门锁定,并且并发性增加很少。

此外,如果读取操作太短,则读写锁定实现(其本身比互斥锁更复杂)的开销可以支配执行成本,特别是因为许多读写锁定实现仍将序列化所有线程通过小部分代码。 最终,只有剖析和测量将确定使用读写锁是否适合您的应用程序。
当前名称:什么是读写锁
转载来于:http://hbruida.cn/article/cjgjso.html