多线程编程实现一个简单的缓存池系统

版权声明:转载请注明来源 https://blog.csdn.net/qq_24598601/article/details/81872366

一、背景

  最近在学习多线程编程,发现实现线程的互斥技术不仅可以用关键字 synchronized,还可以用 java.util.concurrent.locks 包下的读写锁类,使用读写锁比使用关键字的效率更高些,当一个线程加了读锁后其他线程也可以加读锁,但不能加写锁,加了写锁就不能加读锁或写锁。
  然后自己用读写锁写了一个简单的缓存系统,完整代码在下面。

二、完整代码

package com.test;

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

public class CacheDemo {

    //缓存区
    private Map<String, Object> cache = new HashMap<String, Object>();

    //new 一个读写锁实例
    private ReadWriteLock rwl = new ReentrantReadWriteLock();
    /**
     * 描述:实现简单的缓存
     * @author 欧阳
     * @param key
     * @return
     */
    public Object getData(String key){
        rwl.readLock().lock();       //上读锁
        Object value = null;
        try{
            value = cache.get(key);//在缓存中取值
            if(value == null){
                //当缓存中 key 对应的值时将读锁打开,加上写锁
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                try{
                    /*
                     * value = cache.get(key);
                     * 这一句的作用是保证当多个线程都取相同key的值时只要第
                     * 一个线程从数据库中拿到了值,其余的线程就不需要再
                     * 去数据库拿了,从缓冲中拿
                     */
                    value = cache.get(key);
                    //当缓存中没有时,从数据库中取值
                    if(value==null){
                        value = "sqlData";//从数据库中取值;
                        cache.put(key, value);//将从数据库中取到的值存到缓冲中
                        //System.out.println(Thread.currentThread().getName() + "从数据库去值");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally{
                    //使用try catch finally 是为了防止死锁
                    //当写入完成后将写锁打开,然后上上读锁
                    rwl.writeLock().unlock();
                }
                //上读锁
                rwl.readLock().lock();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            //使用try catch finally 是为了防止死锁
            //打开读锁
            rwl.readLock().unlock();
        }
        return value;
    }

    //主方法,测试
    public static void main(String[] args) {
        final CacheDemo cache = new CacheDemo();
        for(int i=0; i<10; i++) {
            new Thread(new Runnable() {
                public void run() {
                    cache.getData("a");
                }
            }).start();
        }
        //System.out.println("已提交");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_24598601/article/details/81872366