栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

读写锁分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

读写锁分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

JAVA代码演示读写锁(通俗易懂)

前言一、读写锁的基本概念二、代码示例

1.同时调用读锁和写锁2.读锁可以相互兼容 总结


前言

多线程是java的一大核心之一,作为一个java工程师,必须把多线程吃透!


提示:以下是本篇文章正文内容,下面案例可供参考

一、读写锁的基本概念

1)首先读写锁是互斥的,两者不能同时在一个线程的同一个资源内存在(比如一个方法内同时存在读锁和写锁,因为借助对象去调用方法,锁粒度的是对象,加之互斥,所以不能同时存在),不然会发生死锁。

2)一个线程获得了某个资源的读锁,其他线程就不能获得这个资源的写锁(这个资源可以抽象为某个对象好理解一些),但是可以获得读锁,这里的读锁可以抽象为对于读操作来说不加锁。

3)一个线程获得了某个资源的写锁,其他资源就不能获取这个资源的读锁和写锁(防止脏读)

4)举个例子,一个类A,分别有三个方法,B()、C()、D(),其中B()加了写锁,C()加了读锁,D()方法中调用了B()和C()方法,此时必然会发生死锁,因为互斥。

二、代码示例 1.同时调用读锁和写锁

代码如下(示例):

class MyCache{
    Map map=new HashMap<>();
    ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
    public void put(String key,Object V){
        try {
        	//加了写锁的方法
            readWriteLock.writeLock().lock();
            map.put(key, V);
        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }finally {
            readWriteLock.writeLock().unlock();
        }

    }


    public void get(int key,Object V){

        try {

            readWriteLock.readLock().lock();//加了读锁
            System.out.println(Thread.currentThread().getName() + "即将写入");
            this.put(String.valueOf(key*3),V);//加了写锁
            System.out.println(Thread.currentThread().getName() + "写入完成");

            System.out.println(Thread.currentThread().getName()+"即将读");
            map.get(key); //加了读锁
            System.out.println(Thread.currentThread().getName()+"读完成");

        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }finally {
            readWriteLock.readLock().unlock();
        }
    }
}

main线程:

public class Lock01 {

    public static void main(String[] args) {
        MyCache myCache=new MyCache();
        
        for (int i=0;i<5;i++) {
            int finalI = i;
            new Thread(() -> {
                myCache.get(finalI,finalI*3);
            }).start();
        }
    }
}

结果:出现死锁导致阻塞

F:jdk11.06binjava.exe "
Thread-0即将写入
Thread-1即将写入
2.读锁可以相互兼容

代码如下(示例):

class MyCache{
    Map map=new HashMap<>();
    ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
    public void put(String key,Object V){
        try {
            readWriteLock.readLock().lock();
            map.put(key, V);
        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }finally {
            readWriteLock.readLock().lock();
            System.out.println("");
        }
    }


    public void get(int key,Object V){

        try {

            readWriteLock.readLock().lock();
            System.out.println(Thread.currentThread().getName() + "即将写入");
            this.put(String.valueOf(key*3),V);//加了读锁
            System.out.println(Thread.currentThread().getName() + "写入完成");


            System.out.println(Thread.currentThread().getName()+"即将读");
            map.get(key); //加了读锁
            System.out.println(Thread.currentThread().getName()+"读完成");

        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }finally {
            readWriteLock.readLock().unlock();
        }
    }
}

结果:不发生堵塞,多条线程均可获得读锁

Thread-2即将写入
Thread-4即将写入

Thread-3即将写入
Thread-1即将写入
Thread-0即将写入

Thread-0写入完成
Thread-0即将读
Thread-0读完成

Thread-1写入完成
Thread-1即将读
Thread-1读完成

Thread-3写入完成
Thread-3即将读
Thread-3读完成
Thread-2写入完成
Thread-2即将读
Thread-2读完成

Thread-4写入完成
Thread-4即将读
Thread-4读完成

Process finished with exit code 0

总结

读写锁的概念可以通过mysql辅助理解,当锁的粒度是一张表,如果这张表加了读锁,那所有的线程都可以读,却不能写,当加了写锁,其他线程不能写也不能读,只能等待获得写锁的线程释放锁。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/731587.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号