zoukankan      html  css  js  c++  java
  • 读写锁

    package com.zhl.practice;
    
    import java.util.Random;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * @author Holley
     * @Description 读写锁(可重入锁Lock,一个读锁可以有多个线程同时获取,同一写锁同一时间只能有一个线程获取,写锁可以降级为读锁(在释放该写锁之前获取读锁,然后释放写锁,称为锁降级))
     * @create 2019-05-27 14:54
     **/
    public class ReadAndWriteLock {
    
        // 共享变量
        private Object data = null;
    
        private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
        // 读取共享变量内容(加上锁之后在一个线程读取数据完成之前不管中间停顿多久其他读取线程都可以插入进来)
        public void getValue(){
            reentrantReadWriteLock.readLock().lock();
            System.out.println(Thread.currentThread().getName() + ":准备读取数据");
            try {
                Thread.sleep(new Random().nextInt(100)*10);
                System.out.println(Thread.currentThread().getName() + ":读取数据" + data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                reentrantReadWriteLock.readLock().unlock();
            }
        }
    
        // 修改共享变量内容(加上锁之后在一个线程写入数据完成之前不管中间停顿多久都没有其他线程会插入进来)
        public void put(Object value){
            reentrantReadWriteLock.writeLock().lock();
            System.out.println(Thread.currentThread().getName() + ":准备修改数据");
            try {
                Thread.sleep(new Random().nextInt(1000)*10);
                data = value;
                System.out.println(Thread.currentThread().getName() + ":修改数据为:" + data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                reentrantReadWriteLock.writeLock().unlock();
            }
        }
    
        public static void main(String[] args){
            final ReadAndWriteLock rwl = new ReadAndWriteLock();
            // 创建多个线程读取数据
            for(int i = 0;i < 5;i++){
                new Thread(() -> {
                    while(true){
                        rwl.getValue();
                    }
                }).start();
            }
            // 创建多个线程修改数据
            for(int i = 0;i < 5;i++){
                new Thread(() -> {
    //                while(true){
                        rwl.put(new Random().nextInt(100));
    //                }
                }).start();
            }
        }
    }

    缓存的demo(hibernate中get和load的区别:load是懒加载,如果查询数据为空时,get方法返回null,而load方法抛出异常)

    public class CacheDemo {
    
        private Map<String, Object> cache = new HashMap<String, Object>();
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
        }
    
        private ReadWriteLock rwl = new ReentrantReadWriteLock();
        public  Object getData(String key){
            rwl.readLock().lock();
            Object value = null;
            try{
                value = cache.get(key);
                if(value == null){
                    rwl.readLock().unlock();
                    rwl.writeLock().lock();
                    try{
                        if(value==null){
                            value = "aaaa";//实际失去queryDB();
                        }
                    }finally{
                        rwl.writeLock().unlock();
                    }
                    rwl.readLock().lock();
                }
            }finally{
                rwl.readLock().unlock();
            }
            return value;
        }
    }
  • 相关阅读:
    覆盖式发布与非覆盖式发布
    GIT
    Web Service返回符合Xml Schema规范的Xml文档
    下拉渐显菜单
    计算网页上坐标的距离
    初识交互设计
    良好用户体验-实现过程!
    做 用户调研?
    这个没什么技术含量,实现起来很简单?
    SQL SERVER 登录问题!该用户与可信的Sql Server连接无关联
  • 原文地址:https://www.cnblogs.com/zhlblogs/p/10931744.html
Copyright © 2011-2022 走看看