Java多线程下ReadWriteLock(读写锁)的使用

  1. 声明读写锁:private ReadWriteLock lock = new ReentrantReadWriteLock();
  2. 独占锁:lock.writeLock()
  3. 共享锁:lock.readLock()



一:无锁案例

在自定义类NoLockTest中存在一个数据变量map,类中存在一个读方法get和写方法put,则在多线程情况下,数据操作会出现错误。


	public class RW {
	    public static void main(String[] args) {
	        NoLockTest my = new NoLockTest();
	
	        //存
	        for (int i = 1; i <=10 ; i++) {
	            final Integer number = i;
	            new Thread(()->{
	                my.put(number+"",number+"");
	            },"Thread"+String.valueOf(i)).start();
	        }
	
	        //取
	        for (int i = 1; i <=10 ; i++) {
	            final Integer number = i;
	            new Thread(()->{
	                my.get(number+"");
	            },"Thread"+String.valueOf(i)).start();
	        }
	
	
	    }
	
	}
	
	//无锁
	class NoLockTest{
	    private volatile Map<String,String> map = new HashMap<>();
	
	    //存
	    public  void put(String key,String value){
	        System.out.println(Thread.currentThread().getName()+"写入"+key);
	        map.put(key,value);
	        System.out.println(Thread.currentThread().getName()+"写入完毕");
	    }
	
	    //取
	    public void get(String key){
	        System.out.println(Thread.currentThread().getName()+"读取"+key);
	        String value = map.get(key);
	        System.out.println(Thread.currentThread().getName()+"读取完毕");
	    }
	
	}


结果:

在这里插入图片描述线程2在写入的时候被插队了,因此就导致线程2还没有写完就被线程1强行写进来了,这样做很明显不符合逻辑。



二:有锁案例

这里的锁并没有使用一般的Lock中的可重入锁,因为Lock锁虽然也能实现线程的有序进行,但lock会将内容直接就给单线程锁死了,可这里针对于map变量的操作情况是:在put数据的时候需要加锁使其有序进行;在get数据的时候无序强调有序进行,因为get操作只牵扯到数据的读取,数据本身不会被改变,因此允许多线程操作反而会有更高的效率。


public class RW {
    public static void main(String[] args) {
        LockTest my = new LockTest();

        //存
        for (int i = 1; i <=10 ; i++) {
            final Integer number = i;
            new Thread(()->{
                my.put(number+"",number+"");
            },"Thread"+String.valueOf(i)).start();
        }

        //取
        for (int i = 1; i <=10 ; i++) {
            final Integer number = i;
            new Thread(()->{
                my.get(number+"");
            },"Thread"+String.valueOf(i)).start();
        }


    }

}




//加锁
class LockTest{
    private volatile Map<String,String> map = new HashMap<>();
    //读写锁
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    //存,一次只允许一个线程操作
    public  void put(String key,String value){
        lock.writeLock().lock();//独占锁
        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();//解锁
        }
    }

    //取,一次可允许多个线程操作
    public void get(String key){
        lock.readLock().lock();//共享锁
        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            String value = map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();//释放锁
        }

    }

}

在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Deeeelete

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值