前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java锁:第四章:读写锁

java锁:第四章:读写锁

作者头像
Java廖志伟
发布2022-09-28 17:03:19
2030
发布2022-09-28 17:03:19
举报
文章被收录于专栏:高级开发进阶

理论:

未使用读写锁的代码:

代码语言:javascript
复制
package com.javaliao.backstage;

import java.util.HashMap;
import java.util.Map;

class Data{
    private volatile Map map = new HashMap<String,Object>();

    //写
    public void put(String key,Object value){
        System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key);
        try {
            Thread.sleep(300);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"\t 写入完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //读
    public void get(String key){
        System.out.println(Thread.currentThread().getName()+"\t 正在读取");
        try {
            Thread.sleep(300);
            Object value = map.get(key);
            System.out.println(Thread.currentThread().getName()+"\t 读取完成:"+value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Demo {

    public static void main(String[] args) {
        Data data = new Data();
        //五个写的线程
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.put(tempInt+"",tempInt+"");
            },String.valueOf(i)).start();
        }
        //五个读的线程
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.get(tempInt+"");
            },String.valueOf(i)).start();
        }
    }
}

控制台:

可以看到写的操作原子性和独占性没有得到保证,0线程正在写入共享资源的时候,其他线程有写入和读取的共享资源操作,导致数据不一致。

是否可以添加Lock锁解决原子性和独占性的问题?

不可以,因为添加

代码语言:javascript
复制
private Lock lock = new ReentrantLock();

只能保证一个线程读,不能让多个线程同时读取,不符合实际需求。

使用ReentrantReadWriteLock解决原子性和独占性,可以很好的解决并发性和数据的一致性

读写锁的代码:

代码语言:javascript
复制
package com.javaliao.backstage;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

class Data{
    private volatile Map map = new HashMap<String,Object>();
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    public void put(String key,Object value){
        //写锁
        lock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key);
            Thread.sleep(300);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"\t 写入完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }

    public void get(String key){
        //读锁
        lock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在读取");
            Thread.sleep(300);
            Object value = map.get(key);
            System.out.println(Thread.currentThread().getName()+"\t 读取完成:"+value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }
}


public class Demo {

    public static void main(String[] args) {
        Data data = new Data();
        //五个写的线程
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.put(tempInt+"",tempInt+"");
            },String.valueOf(i)).start();
        }
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(()->{
                data.get(tempInt+"");
            },String.valueOf(i)).start();
        }
    }
}

控制台:

比较:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理论:
  • 是否可以添加Lock锁解决原子性和独占性的问题?
  • 使用ReentrantReadWriteLock解决原子性和独占性,可以很好的解决并发性和数据的一致性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档