基于ReentrantLock封装的字符串锁的场景与实现

1.场景

ktv,包间,订单

在ktv针对具体包间下单时,是需要加锁去实现的,不然有可能同一个包间同时产生2个订单

但是锁加在哪里?加在包间对象?NO!

因为“包间”对象从数据库里查询出来的,不是单实例的对象。

加在方法?或者代码块?NO!

如果加在方法或者代码块,会导致所有下单操作被阻塞,因为整个ktv所有影厅的下单代码是同一块

这也不行,那也不行,怎么办?有没有一种方法可以针对“包间”的id或name等唯一属性加锁?能!!!


2.基于ReentrantLock封装的字符串参数的锁

使用方式如下:

LockKey是一个String类型的,可以是id,name的一些对象的简单属性

ResourceLock.accquireWrite(LockKey);
...
...
ResourceLock.releaseWrite(LockKey);
实现代码如下:

SysnKeyLock.java:继承ReentrantLock

public class SysnKeyLock extends ReentrantLock {
    private static final long serialVersionUID = 1478211960393710925L;
    String key;

    public SysnKeyLock(String key) {
        this.key = key;
    }

    public String getKey() {
        return this.key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}

SysnLockPool.java:维护一个HashTable,记录String-Lock的对应关系,cache记录已经创建过的对象

import java.util.Hashtable;
import org.apache.commons.collections.map.LRUMap;

public class SysnLockPool {
    private static final int poolSize = 10000;
    private Hashtable<String, SysnKeyLock> core = new Hashtable();
    private LRUMap cache = new LRUMap(10000);

    public SysnLockPool() {
    }

    public synchronized SysnKeyLock getLock(String resourceID) {
        SysnKeyLock lock = (SysnKeyLock)this.core.get(resourceID);
        if(lock == null) {
            lock = (SysnKeyLock)this.cache.get(resourceID);
            if(lock == null) {
                lock = new SysnKeyLock(resourceID);
            } else {
                this.cache.remove(resourceID);
            }

            this.core.put(resourceID, lock);
        }

        return lock;
    }

    public synchronized void releaseLock(SysnKeyLock lock) {
        this.core.remove(lock.getKey());
        this.cache.put(lock.getKey(), lock);
    }
}

ResourceLock.java

public class ResourceLock {
    static SysnLockPool rtLockPool = new SysnLockPool();

    public ResourceLock() {
    }

    public static SysnKeyLock accquireWrite(String resourceID) {
        SysnKeyLock lock = rtLockPool.getLock(resourceID);
        lock.lock();
        return lock;
    }

    public static void releaseWrite(String resourceID) {
        SysnKeyLock lock = rtLockPool.getLock(resourceID);
        lock.unlock();
        rtLockPool.releaseLock(lock);
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值