读写锁应用实例(ReentrantReadWriteLock)及Synchronized比较分析

以下知识参考至《Java并发编程的艺术》

这里使用的是读写锁:ReentrantReadWriteLock

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

public class Cache {
    static Map<String,Object> map = new HashMap<String, Object>();
    static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    static Lock readLock = readWriteLock.readLock();
    static Lock writeLock = readWriteLock.writeLock();
    
    public static final Object getByKey(String key){
        readLock.lock();
        try{
            return map.get(key);
        }finally{
            readLock.unlock();
        }
    }
    
    public static final Object getMap(){
        readLock.lock();
        try{
            return map;
        }finally{
            readLock.unlock();
        }
    }
    
    public static final Object put(String key,Object value){
        writeLock.lock();
        try{
            return map.put(key, value);
        }finally{
            writeLock.unlock();
        }
    }
    
    public static final Object remove(String key){
        writeLock.lock();
        try{
            return map.remove(key);
        }finally{
            writeLock.unlock();
        }
    }
    
    public static final void clear(){
        writeLock.lock();
        try{
            map.clear();
        }finally{
            writeLock.unlock();
        }
    }
    
    public static void main(String[] args) {
        List<Thread> threadList = new ArrayList<Thread>();
        for(int i =0;i<6;i++){
            Thread thread = new PutThread();
            threadList.add(thread);
        }
        for(Thread thread : threadList){
            thread.start();
        }
        put("ji","ji");
        System.out.println(getMap());
    }
//上面的代码我在测试的时候居然出现了java.util.ConcurrentModificationException异常,请问有没有大神能够解答
    
    private static class PutThread extends Thread{
        public void run(){
            put(Thread.currentThread().getName(),Thread.currentThread().getName());
        }
    }
}
在Java5之前我们一般这样去实现:
import java.util.HashMap;
import java.util.Map;

public class CacheSyn {
    static Map<String, Object> map = new HashMap<String, Object>();
    private static final String mapLockStr = "mapLockStr";

    public  static final Object getByKey(String key) {
      //以字符串mapLockStr为锁    
       synchronized(mapLockStr.intern()){
            return map.get(key);
        }
    }

    public static final Object getMap() {
        synchronized(mapLockStr.intern()){
            return map;
        }
    }

    public static final Object put(String key, Object value) {
        synchronized(mapLockStr.intern()){
            return map.put(key, value);
        }
    }

    public static final Object remove(String key) {
        synchronized(mapLockStr.intern()){
            return map.remove(key);
        }
    }

    public static final void clear() {
        synchronized(mapLockStr.intern()){
            map.clear();
        }
    }

    public static void main(String[] args) {
        List<Thread> threadList = new ArrayList<Thread>();
        for(int i =0;i<6;i++){
            Thread thread = new PutThread();
            threadList.add(thread);
        }
        for(Thread thread : threadList){
            thread.start();
        }
        put("ji", "ji");
        System.out.println(getMap());
    }

    private static class PutThread extends Thread {
        public void run() {
            put(Thread.currentThread().getName(), Thread.currentThread().getName());
        }
    }
}
//上面的代码我在测试的时候居然出现了java.util.ConcurrentModificationException异常,请问有没有大神能够解答

在锁的获取上:

1、读写锁(其实Lock的实现类都一样):都需要通过调用lock()方法来显示获取锁,并且在使用完之后也要调用unlock()方法显示释放锁,获取和释放都是主动的过程。注意:如果在调用unlock()方法之前方法就抛出异常,锁将无法释放建议锁的释放放在finally代码块中执行
2、Synchronized:这里我是使用同步代码块的形式实现同步的,当进入某个Synchronized(object)修饰的代码块之前,该对象必须要获得object这个锁对象,才能进去向下执行,而且一次只能进一个。代码块执行完毕,锁会自动释放。

性能比较:

  1. 当没有写操作时,ReentrantReadWriteLock方式允许同一时间多个线程读取。而Synchronized方式却不行,所以在并发性能上ReentrantReadWriteLock更优。
  2. ReentrantReadWriteLock方式相较于Synchronized方式的等待通知机制实现方式更加明了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,373评论 11 349
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,778评论 18 399
  • 一、多线程 说明下线程的状态 java中的线程一共有 5 种状态。 NEW:这种情况指的是,通过 New 关键字创...
    Java旅行者阅读 4,751评论 0 44
  • 情人的泪,一滴就醉;多情的心,一揉就碎;爱情这杯酒,谁喝都得醉……
    冥冥中的旅行阅读 98评论 0 0
  • 火箭小妹今天要向大家介绍一款最近在 KickStarter 上众筹很火热的纸质笔记本产品,名字叫做“RocketB...
    效率火箭阅读 855评论 1 5