欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

读锁(共享锁)写锁(独占锁)解析

程序员文章站 2022-11-30 14:30:01
读锁(共享锁)写锁(独占锁)解析在多线程环境下一个资源类被读是没有任何问题的,所以满足并发要求,但是,如果有一个线程去写共享资源,那么就不应该再有其他线程可以对该资源进行读或写了。也就是说,读-读可以共存,读-写不能共存,写-写不能共存。举例说明:首先我们手写一个缓存类,不加锁看执行结果package com.example.demo;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import...

读锁(共享锁)写锁(独占锁)解析
在多线程环境下一个资源类被读是没有任何问题的,所以满足并发要求,但是,如果有一个线程去写共享资源,那么就不应该再有其他线程可以对该资源进行读或写了。也就是说,读-读可以共存,读-写不能共存,写-写不能共存。
举例说明:
首先我们手写一个缓存类,不加锁看执行结果

package com.example.demo;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.TimeUnit;


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

    public void put(String key,Object value){
        System.out.println(Thread.currentThread().getName()+"\t正在写入:"+value);
        //模拟网络通信延迟
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        }catch (Exception e){
            e.printStackTrace();
        }
        map.put(key,value);
        System.out.println(Thread.currentThread().getName()+"\t正在写成:");
    }

    public void get(String key){
        System.out.println(Thread.currentThread().getName()+"\t正在读取:");
        //模拟网络通信延迟
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        }catch (Exception e){
            e.printStackTrace();
        }
        Object result=map.get(key);
        System.out.println(Thread.currentThread().getName()+"\t读取完成:"+result);
    }
}
/**
 * Created by Administrator on 2020/7/5.
 *  读写锁讲解
 *  1.读锁(共享锁)
 *  2.写锁(独占锁)
 * @author qtx
 */
public class ReadAndWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache=new MyCache();
        //5个线程写
        for (int i = 0; i < 5; i++) {
            final int temp=i;
            new Thread(() -> {
              myCache.put(temp+"",temp+"");
            }).start();
        }

        //5个线程读
        for (int i = 0; i < 5; i++) {
            final int temp=i;
            new Thread(() -> {
                myCache.get(temp+"");
            }).start();
        }
    }
}

读锁(共享锁)写锁(独占锁)解析
可以看出,写没有完成,就被读取操作进行加塞
加塞读写锁之后效果

package com.example.demo;

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


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

    public void put(String key, Object value) {
        //加入读锁
        rwLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + "\t正在写入:" + value);
            //模拟网络通信延迟
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            map.put(key, value);
            System.out.println(Thread.currentThread().getName() + "\t写入完成:");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rwLock.writeLock().unlock();
        }

    }

    public void get(String key) {
        //加入写锁
        rwLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + "\t正在读取:");
            //模拟网络通信延迟
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Object result = map.get(key);
            System.out.println(Thread.currentThread().getName() + "\t读取完成:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rwLock.readLock().unlock();
        }

    }
}

/**
 * Created by Administrator on 2020/7/5.
 * 读写锁讲解
 * 1.读锁(共享锁)
 * 2.写锁(独占锁)
 *
 * @author qtx
 */
public class ReadAndWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        //5个线程写
        for (int i = 0; i < 5; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.put(temp + "", temp + "");
            }).start();
        }

        //5个线程读
        for (int i = 0; i < 5; i++) {
            final int temp = i;
            new Thread(() -> {
                myCache.get(temp + "");
            }).start();
        }
    }
}

读锁(共享锁)写锁(独占锁)解析
运行结果满足要求,只有先全部写完,才能进行读取

本文地址:https://blog.csdn.net/u014385267/article/details/107145045