当前位置: 首页 > 面试题库 >

基于Java名称的锁?

韩季
2023-03-14
问题内容

MySQL具有方便的功能:

SELECT GET_LOCK("SomeName")

这可用于为应用程序创建简单但非常具体的基于名称的锁。但是,它需要数据库连接。

我有很多情况,例如:

someMethod() {
    // do stuff to user A for their data for feature X
}

简单地同步此方法是没有意义的,因为,例如,如果在此期间同时为用户B调用了此方法,则用户B无需等待用户A完成操作就可以开始操作,而只需为用户进行操作A和功能X的组合需要等待。

使用MySql锁,我可以执行以下操作:

someMethod() {
    executeQuery("SELECT GET_LOCK('userA-featureX')")
    // only locked for user A for their data for feature X
    executeQuery("SELECT RELEASE_LOCK('userA-featureX')")
}

由于Java锁定基于对象,因此似乎需要创建一个新对象来表示此锁定的情况,然后将其放在某个位置的静态缓存中,以便所有线程都可以看到它。随后针对该情况进行锁定的请求将在高速缓存中定位锁定对象并获取其锁定。我试图创建类似这样的东西,但是锁缓存本身需要同步。而且,很难检测何时不再使用锁定对象,以便可以将其从缓存中删除。

我已经看过Java并发包,但是没有什么能够处理这样的事情了。有没有简单的方法可以实现此目的,还是我从错误的角度看待这个问题?

编辑:

为了明确起见,我不希望提前创建预定义的锁池,而是希望根据需要创建它们。我在想的一些伪代码是:

LockManager.acquireLock(String name) {
    Lock lock;  

    synchronized (map) {
        lock = map.get(name);

        // doesn't exist yet - create and store
        if(lock == null) {
            lock = new Lock();
            map.put(name, lock);
        }
    }

    lock.lock();
}

LockManager.releaseLock(String name) {
    // unlock
    // if this was the last hold on the lock, remove it from the cache
}

问题答案:

我看到的所有答案都太复杂了。为什么不简单使用:

public void executeInNamedLock(String lockName, Runnable runnable) {
  synchronized(lockName.intern()) {
    runnable.run();
  }
}

关键是方法intern:它确保返回的String是全局唯一对象,因此可以用作vm-instance-wide互斥量。所有的Interned Strings都保存在一个全局池中,因此这就是你在原始问题中所讨论的静态缓存。不用担心内存泄漏;如果没有其他线程引用这些字符串,则这些字符串将被gc’ed。但是请注意,直到(包括Java6)该池都保留在PermGen空间而不是堆中,因此你可能必须增加它。

但是,如果vm中的某些其他代码由于完全不同的原因而锁定在同一字符串上,则会出现一个问题,但是a)这种可能性很小,b)你可以通过引入名称空间来解决它,例如 executeInNamedLock(this.getClass().getName() + "_" + myLockName);



 类似资料:
  • 本文向大家介绍获取Java中基本类型的名称,包括了获取Java中基本类型的名称的使用技巧和注意事项,需要的朋友参考一下 该方法用于获取由类对象表示的实体名称,例如原始类型,接口,类,数组类,void等。这些名称以字符串形式返回。 给出了使用方法获得基本类型名称的程序,如下所示: 示例 输出结果 现在让我们了解上面的程序。 该方法用于获取原始数据类型的名称float,int和char。然后将这些名称

  • 问题内容: 我想从我的接口对象获取实现类名称-有什么方法可以做到这一点? 我知道我可以用来检查实现对象,但是在我的应用程序中,有将近20到30个实现相同接口的类可以重写一个特定方法。 我想弄清楚它将要调用的特定方法。 问题答案: 只需使用-它会返回用于实现接口的运行时类:

  • 我有一个类(消息),它有一些实例变量。其中一个变量的类型是interface(MessageContent)。在将这个类序列化为json的过程中,我希望使用依赖于实现的名称序列化这个变量(内容)。下面是详细信息的代码片段: 我的要求是,当消息序列化并且内容类型为VideoMessage时,序列化的json应该是: 如何通过fasterxml Jackson实现?我正在使用ObjectMapper的

  • 问题内容: 最近,我对CSS选择器进行了一些研究,并遇到了有关新“ data- *”属性的问题。 我了解,为了选择具有data属性的元素,有几种解决方法: 这些还有其他变体,但我的问题与CSS选择器有关,该选择器可以定位仅具有“数据”属性的元素。更具体地说,是否有CSS选择器可以定位完全具有ANY“数据”属性的元素? 虽然不正确,但我在想类似的东西: 我一直在搜索Google,但尚未找到有关该属性