我不是程序猿,请叫我攻城狮@IT·互联网手机移动程序开发

读写锁应用实例(ReentrantReadWriteLock)及

2017-02-08  本文已影响48人  higher2017

以下知识参考至《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方式的等待通知机制实现方式更加明了。
上一篇下一篇

猜你喜欢

热点阅读