栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

任意键的锁定处理程序

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

任意键的锁定处理程序

您无需尝试将大小限制为任意值-事实证明,您可以完成这种“锁定处理程序”惯用语,而仅存储当前在映射中锁定的键的 确切 数目。

这个想法是使用一个简单的约定:成功地 映射 添加
到映射计数为“锁定”操作,而将其删除则作为“解锁”操作。巧妙地避免了在某些线程仍处于锁定状态和其他竞争条件的情况下删除映射的问题。

此时,

value
映射中的in仅用于阻止使用相同密钥到达的其他线程,并且需要等待直到删除映射为止。

这是一个示例1,其中包含

CountDownLatch
而不是
Lock
作为地图值:

public void handle(Key key) throws InterruptedException {    CountDownLatch latch = new CountDownLatch(1);    // try to acquire the lock by inserting our latch as a    // mapping for key while(true) {        CountDownLatch existing = lockMap.putIfAbsent(key, latch);        if (existing != null) { // there is an existing key, wait on it existing.await();        } else { break;        }    }    try {        externalSystem.process(key);    } finally {        lockMap.remove(key);        latch.countDown();    }}

在此,映射的生存期只有保持锁定的时间。映射将永远不会有比同时请求不同密钥更多的条目。

与您的方法的区别在于,不会“重用”映射-
每个

handle
调用都会创建一个新的闩锁和映射。由于您已经在进行昂贵的原子操作,因此这实际上不太可能会变慢。另一个缺点是,在有许多等待线程的情况下,当闩锁递减计数时,
所有 线程 都会 被唤醒,但是只有一个线程能够成功放入新的映射并因此获得锁-其余的则重新进入新锁的睡眠状态。

可以
构建此版本的另一个版本,该版本在线程进入并等待现有映射时重新使用映射。基本上,解锁线程只是对等待线程之一进行“切换”。只有一个映射将用于等待相同键的整个线程集-
它按顺序移交给每个线程。该大小仍受限制,因为没有更多线程在等待给定的映射,因此仍将其删除。

要实现这一点,您

CountDownLatch
可以用一个可以计算等待线程数的映射值代替。当线程进行解锁时,它首先检查是否有线程在等待,如果有,则唤醒它进行切换。如果没有线程在等待,它将“销毁”对象(即设置一个标志,表明该对象不再在映射中)并将其从映射中删除。

您需要在适当的锁定下进行上述操作,并且有一些棘手的细节。在实践中,我发现上面简短而甜美的示例非常有用。


1即时编写,未经编译且未经测试,但该想法有效。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/508443.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号