天天看點

java并發程式設計-讀寫鎖

最近項目中需要用到讀寫鎖

讀寫鎖适用于讀操作多,寫操作少的場景,假設你的程式中涉及到對一些共享資源的讀和寫操作,且寫操作沒有讀操作那麼頻繁。在沒有寫操作的時候,兩個線程同時讀一個資源沒有任何問題,是以應該允許多個線程能在同時讀取共享資源。但是如果有一個線程想去寫這些共享資源,就不應該再有其它線程對該資源進行讀或寫,也就是說 讀-讀能共存,讀-寫不能共存,寫-寫不能共存

我們直接使用java的讀寫鎖  ReadWriteLock

如下代碼是使用緩存的典型場景:

public class ReadWriteLockTest {

    private static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    private static LoadingCache<Long, LinkModel> windowCache = CacheBuilder
            .newBuilder()
            .expireAfterWrite(Config.ALL_RELOAD_CYCLE+1,TimeUnit.HOURS) //寫入ALL_RELOAD_CYCLE小時後remove掉
            .build(new CacheLoader<Long, LinkModel>() {
                @Override
                public LinkModel load(Long key) throws Exception {
                    return LinkModelDAO.getLinkModelWindow(key);
                }
            });


    public static LinkModel getLinkModelWindow(long linkId) {
        try {
            readWriteLock.readLock().lock();
            LinkModel model = windowCache.get(linkId);
            return model;
        } catch (ExecutionException e) {
            LOGGER.error(e.getMessage(), e);
        }finally {
            readWriteLock.readLock().unlock();
        }
        return null;
    }


    public static  void refershModelWindowCache(String partitionId){

        try {
            readWriteLock.writeLock().lock();
            HashMap<Long, LinkModel> linkModelHashMap = LinkModelDAO.getLinkModelWindowsByPartition(partitionId,Config.ALL_ROADCLASS_LIST);
            if(MapUtils.isNotEmpty(linkModelHashMap)){
                windowCache.cleanUp();
                windowCache.putAll(linkModelHashMap);
            }
        } catch (EventMiningException e) {
            LOGGER.error(e.getMessage(), e);
        }finally {
            readWriteLock.writeLock().unlock();
        }

    }
}      

 下面這篇文章寫得比較詳細:

 http://ifeve.com/read-write-locks/