ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-ConcurrentHashMap中基于番石榴的信号量与信号量

2019-11-19 22:03:28  阅读:223  来源: 互联网

标签:concurrency guava semaphore java


我的应用程序中需要一个基于密钥的Semaphore机制,偶然发现Guava是Striped.semaphore(int, int).但是,它的行为不符合预期.

使用以下代码,提取有时会返回null.两种方法均由不同的线程访问.我希望调用fetch的线程可以等待,直到地图上有Blubb可用.

private final Striped<Semaphore> semaphores = Striped.semaphore(64, 0);

private final Map<String, Blubb> blubbs = Collections.synchronizedMap(new HashMap<String, Blubb>());

private Semaphore getSemaphore(final String key) {
    return semaphores.get(key);
}

@Override
public void put(String key, Blubb blubb)  {
    blubb.put(key, blubb);
    final Semaphore semaphore = getSemaphore(toUser);
    semaphore.release();
}

@Override
public blubb fetch(final String key) {
    try {
        final Semaphore semaphore = getSemaphore(key);
        final boolean acquired = semaphore.tryAcquire(30, TimeUnit.SECONDS);
        return blubbs.get(key);
    } catch (final InterruptedException e) {
        e.printStackTrace();
    }

    return null;
}

如果我使用以下代码切换回基本Java,一切都会按预期进行.

private final Map<String, Semaphore> semaphoresMap = new ConcurrentHashMap<String, Semaphore>();

private Semaphore getSemaphore(final String key) {
    Semaphore semaphore = semaphoresMap.get(key);
    if (semaphore == null) {
        semaphore = new Semaphore(0);
        semaphoresMap.put(key, semaphore);
    }
    return semaphore;
}

我在这里想念什么?谢谢

解决方法:

Guava的Striped指定多个键可能潜在地映射到相同的信号量.从Javadoc:

The guarantee provided by this class is that equal keys lead to the same lock (or semaphore), i.e. if (key1.equals(key2)) then striped.get(key1) == striped.get(key2) (assuming Object.hashCode() is correctly implemented for the keys). Note that if key1 is not equal to key2, it is not guaranteed that striped.get(key1) != striped.get(key2); the elements might nevertheless be mapped to the same lock. The lower the number of stripes, the higher the probability of this happening.

代码中的基本假设似乎是,如果与特定对象关联的信号量具有许可,则该对象在映射中具有一个条目,但事实并非如此-如果映射中存在另一个对象的条目碰巧与同一个信号量相关联,那么该许可可能由对完全不同的对象的访存获取,而该对象实际上在映射中没有任何条目.

标签:concurrency,guava,semaphore,java
来源: https://codeday.me/bug/20191119/2039272.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有