Java独占锁/共享锁/互斥锁解析举例

364 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

独占锁(写锁)/共享锁(读锁1)/互斥锁

独占锁:指该锁一次只能被-一个线程所持有。对ReentrantLock和Synchronized而言都是独占锁

共享锁:指该锁可被多个线程所持有。

对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。

读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。

读写锁:

例子:登记口的航情,读所有乘客,写只能一个人写

多个线程同时读一个资源类没有任何问题,所以为了“满足并发量,读取共享资源应该可以同时进行。

但是如果有一个线程想去写共享资源来,就不应该再有其它线程可以对该资源进行读或写

读-读能共存

读-写不能共存

写-写不能共有

image.png

可读可写绝对业务需求 redis

缓存三大特征:读,写,关闭(清缓存)

kv键值对,重要的是k,不是value,因为k唯一

写操作:洗澡不能洗一半,车队不能被打断(原子性)+独占

必须要加volatile因为保证可见性(航班延误需要第一时间通知)

读写分离 同时贡献

为什么lock能取代sync

sync相当于你上个厕所把学校大门都锁到了 并发性比较差

package com.wsx.readWriteLock;

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

    /**
     * 读写锁
     */
    class Cache{

        private volatile Map<String,Object> map = new HashMap<String,Object>();
        private ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();

        public void put(String key,Object object){
            //模块化编程
            rwlock.writeLock().lock();
            try {
                System.out.println(Thread.currentThread().getName()+"正在写入......"+key);
                try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
                map.put(key,object);
                System.out.println(Thread.currentThread().getName()+"写入完成......");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                rwlock.writeLock().unlock();
            }
        }

        public void get(String key){
            rwlock.readLock().lock();
            try {
                System.out.println(Thread.currentThread().getName()+"正在读取......");
                try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
                Object result = map.get(key);
                System.out.println(Thread.currentThread().getName()+"读取完成......"+result);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                rwlock.readLock().unlock();
            }
        }
    }

    public class ReadWriteLockDemo {
        public static void main(String[] args) {

            Cache cache = new Cache();

            for (int i = 0; i < 5; i++) {

                final int tempint = i;

                new Thread(()->{
                    cache.put(tempint+" ",tempint+" ");
                },String.valueOf(i)).start();
            }

            for (int i = 0; i < 5; i++) {

                final int tempint = i;

                new Thread(()->{
                    cache.get(tempint+" ");
                },String.valueOf(i)).start();
            }
        }
    }