java多线程-读写锁ReadWriteLock

先来看看官方文档:
在这里插入图片描述通过代码演示:
未加读写锁的时候:

package com.readWrite;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo01 {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i = 1; i < 5; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.put(temp+"",temp+"");
            },String.valueOf(i)).start();}for (int i = 1; i < 5; i++) {final int temp = i;new Thread(()->{
​                myCache.get(temp+"");},String.valueOf(i)).start();}}

}
/*
自定义缓存
 */
class MyCache{
    private volatile Map<String,Object> map =new HashMap<>();
    //存,写
    public void put(String key,Object 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);
​        Object o = map.get(key);
​        System.out.println(Thread.currentThread().getName()+"读取完毕"+key);}
}
class MyCacheLock{//用synchronized,lock都能实现,但是如果希望写的时候只有一个线程.而读的时候,所有线程都能读.则就用读写锁就好了private volatile Map<String,Object> map =new HashMap<>();//读写锁.更加细粒度的控制private ReadWriteLock readWriteLock =new ReentrantReadWriteLock();//存,写 .写入的时候只希望同时只有一个线程写public void put(String key,Object value){
​        readWriteLock.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 {
​            readWriteLock.writeLock().unlock();}}//取,读.读的时候所有人都可以读public void  get(String key){
​        readWriteLock.readLock().lock();try{
​            System.out.println(Thread.currentThread().getName()+"读取中"+key);
​            Object o = map.get(key);
​            System.out.println(Thread.currentThread().getName()+"读取完毕"+key);}catch (Exception e){
​            e.printStackTrace();}finally {
​            readWriteLock.readLock().unlock();}}
}

在1写入的时候,还没等1写入完成就有其他线程开始插队写了,所以保证1写入后要等1写入完成,才能进来其他线程.

细粒度问题:用synchronized,lock都能实现,但是如果希望写的时候只有一个线程.而读的时候,所有线程都能读.则就用读写锁就好了

改进后的代码:

package com.readWrite;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**

 * 独占锁(写锁),一次只能被一个线程占有

 * 共享锁:(读锁) 多个线程可以同时占有

 * ReadWriteLock

 * 读-读 可以共存

 * 读-写 不能共存

 * 写-写 不能共存
   */
   public class ReadWriteLockDemo01 {
   public static void main(String[] args) {
       MyCacheLock myCache = new MyCacheLock();
       for (int i = 1; i < 5; i++) {
           final int temp = i;
           new Thread(()->{
               myCache.put(temp+"",temp+"");
           },String.valueOf(i)).start();}for (int i = 1; i < 5; i++) {final int temp = i;new Thread(()->{
   ​            myCache.get(temp+"");},String.valueOf(i)).start();}

   }

}
/*
自定义缓存
 */
class MyCache{
    private volatile Map<String,Object> map =new HashMap<>();
    //存,写
    public void put(String key,Object 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);
​        Object o = map.get(key);
​        System.out.println(Thread.currentThread().getName()+"读取完毕"+key);}
}
class MyCacheLock{//用synchronized,lock都能实现,但是如果希望写的时候只有一个线程.而读的时候,所有线程都能读.则就用读写锁就好了private volatile Map<String,Object> map =new HashMap<>();//读写锁.更加细粒度的控制private ReadWriteLock readWriteLock =new ReentrantReadWriteLock();//存,写 .写入的时候只希望同时只有一个线程写public void put(String key,Object value){
​        readWriteLock.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 {
​            readWriteLock.writeLock().unlock();}}//取,读.读的时候所有人都可以读public void  get(String key){
​        readWriteLock.readLock().lock();try{
​            System.out.println(Thread.currentThread().getName()+"读取中"+key);
​            Object o = map.get(key);
​            System.out.println(Thread.currentThread().getName()+"读取完毕"+key);}catch (Exception e){
​            e.printStackTrace();}finally {
​            readWriteLock.readLock().unlock();}}
}

在这里插入图片描述
写的每个线程,都必须写入完毕后才能进行下一个线程.

原创文章 32 获赞 52 访问量 640

猜你喜欢

转载自blog.csdn.net/qq_42400763/article/details/105821042