我想在Web java应用程序中实现对重量级对象的简单缓存.但我无法弄清楚如何正确地做到这一点.
我错过了什么或ConcurrentHashMap方法(putIfAbsent,...)是不够的,需要额外的同步?
是否有更好的简单API(在内存中,没有外部配置)来做到这一点?
P.
我使用LinkedHashMap了accessOrdertrue,随时允许最多500个条目作为数据的LRU缓存.但由于可扩展性问题,我想转向一些线程安全的替代方案.ConcurrentHashMap在这方面似乎很好,但缺乏的特点accessOrder和removeEldestEntry(Map.Entry e)发现LinkedHashMap.任何人都可以指向某些链接或帮助我简化实施.
java performance multithreading concurrenthashmap linkedhashmap
我有一个项目,我用jdk 6,7,8构建这个项目,我的目标是1.6
当我构建jdk 8时,我收到此错误:
Undefined reference: java.util.concurrent.ConcurrentHashMap.KeySetView java.util.concurrent.ConcurrentHashMap.keySet()
因为我在这行中有这个代码:
final Iterator<CLASS_NAME> itr = hashMap.keySet().iterator();
Run Code Online (Sandbox Code Playgroud)
如何避免错误,我在互联网上进行了一些搜索,并且由于java 8改变了它的返回类型键集,我得到了错误.这是任何解决方案.我正在使用maven,而animal-sniffer-plugin会出现此错误,并出现签名错误.
假设我有一个带有集合的并发映射值:
Map<Integer, List<Integer> map = new ConcurrentHashMap<>();
map.putIfAbsent(8, new ArrayList<>());
Run Code Online (Sandbox Code Playgroud)
我更新了如下值:
map.computeIfPresent(8, (i, c) -> {
c.add(5);
return c;
});
Run Code Online (Sandbox Code Playgroud)
我知道computeIfPresent整个方法调用是以原子方式执行的.但是,考虑到这个映射是由多个线程同时访问的,我有点担心对底层集合所做的修改的数据可见性.在这种情况下,调用后将在列表中看到值5map.get
我的问题是map.get如果在computeIfPresent方法调用中执行了更改,则在调用时将更改为列表在其他线程中可见.
请注意,如果我在执行更新操作之前参考列表,我知道列表的更改将不可见.如果我map.get在更新操作后引用列表(通过调用),我不确定列表的更改是否可见.
我不确定如何解释文档,但在我看来发生这种情况 - 在关系之前将保证在这种特定情况下对底层集合的更改的可见性
更正式地说,给定密钥的更新操作承担与该密钥的任何(非空)检索之前发生的关系,报告更新的值
我有一个ConcurrentHashMap,我在其中执行以下操作:
sequences = new ConcurrentHashMap<Class<?>, AtomicLong>();
if(!sequences.containsKey(table)) {
synchronized (sequences) {
if(!sequences.containsKey(table))
initializeHashMapKeyValue(table);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是 - 是否没有必要做额外的事情
if(!sequences.containsKey(table))
Run Code Online (Sandbox Code Playgroud)
检查synschronized块内部,以便其他线程不会初始化相同的hashmap值?
也许检查是必要的,我做错了?我正在做的事似乎有点傻,但我认为这是必要的.
我需要一张符合以下要求的地图:
它应该是高度并发的.的put(),get()并且remove()方法可同时被多个线程调用.
它应该是固定的大小.如果HashMap达到最大值的大小(例如10000),则不应允许向地图添加新条目.它不能是LRU缓存,其中最旧的条目在达到最大大小时被删除.
ConcurrentHashMap可能满足#1.但是,不确定如何在ConcurrentHashMap不影响并发性的情况下实现#2 (添加自定义put()方法,只有当大小小于最大大小时才会添加到地图中,需要"同步".这将失败目的使用并发HashMap).
请让我知道你的想法.
java concurrency multithreading concurrenthashmap java.util.concurrent
我试图简单地在ConcurrentHashMap中打印所有键/值对.
我在网上找到了这个代码,我认为会这样做,但它似乎是获取有关桶/哈希码的信息.其实说实话输出很奇怪,可能我的程序不正确,但我首先要确保这部分是我想要使用的.
for (Entry<StringBuilder, Integer> entry : wordCountMap.entrySet()) {
String key = entry.getKey().toString();
Integer value = entry.getValue();
System.out.println("key, " + key + " value " + value);
}
Run Code Online (Sandbox Code Playgroud)
这为大约10个不同的键提供输出,其计数似乎是映射到插入的总插入数的总和.
我编写了一个计时器,用于衡量任何多线程应用程序中特定代码的性能.在下面的计时器中,它还将使用x毫秒的数量填充地图.我将使用这张地图作为我的直方图的一部分来进行进一步的分析,比如这几分钟的调用百分比等等.
public static class StopWatch {
public static ConcurrentHashMap<Long, Long> histogram = new ConcurrentHashMap<Long, Long>();
/**
* Creates an instance of the timer and starts it running.
*/
public static StopWatch getInstance() {
return new StopWatch();
}
private long m_end = -1;
private long m_interval = -1;
private final long m_start;
private StopWatch() {
m_start = m_interval = currentTime();
}
/**
* Returns in milliseconds the amount of time that has elapsed since the timer was created. If the
* …Run Code Online (Sandbox Code Playgroud) 这可能是一个重复的问题,但我在一本关于并发的书中找到了这部分代码.这据说是线程安全的:
ConcurrentHashMap<String, Integer> counts = new ...;
private void countThing(String thing) {
while (true) {
Integer currentCount = counts.get(thing);
if (currentCount == null) {
if (counts.putIfAbsent(thing, 1) == null)
break;
} else if (counts.replace(thing, currentCount, currentCount + 1)) {
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
从我的(并发初学者)的角度来看,线程t1和线程t2都可以读取currentCount = 1.然后两个线程都可以将地图的值更改为2.有人可以解释我代码是否正常?
java concurrency multithreading concurrenthashmap concurrent-programming
我正在尝试找到这些答案,但无法在Google或Java文档中理解(或确认)它.
我的实现看起来像这样:
Map<String, POJO> map = new ConcurrentHashMap<String, POJO>();
Run Code Online (Sandbox Code Playgroud)
如果我做
value1 = map.get(key1);
value1.setProp(prop);
Run Code Online (Sandbox Code Playgroud)
任何其他线程可能会覆盖.
现在,我在想如果我喜欢以下内容:它会是一个原子操作/换句话说,它会阻止key1段吗?
map.compute(key1, (key1, value1) -> { value1.setProp(prop) });
Run Code Online (Sandbox Code Playgroud)
Javadoc的compute功能
尝试计算指定键及其当前映射值的映射(如果没有当前映射,则为null).整个方法调用以原子方式执行.其他线程在此映射上的某些尝试更新操作可能在计算进行时被阻止,因此计算应该简短,并且不得尝试更新此Map的任何其他映射.
参考文献:
1. https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html 2. https://docs.oracle.com/javase/8/docs/api/java /util/concurrent/ConcurrentHashMap.html#compute-K-java.util.function.BiFunction-
对于我的最终实现,我做了类似这样的事情,因为所有线程共享NewMap,最后,我新的POJO列表
抽象数据类型
public class NewMap {
private Map<String, POJO> map;
private boolean isUpdatable;
void NewMap(){
isUpdatable = true;
map = new ConcurrentHashMap();
}
void putPOJOProp1(String key, Type value) throws ReadOnlyException{
map.compute(key, (k,v) -> {
if(!isUpdatable) throw new ReadOnlyException();
if(k == null){
POJO p = new POJO(); …Run Code Online (Sandbox Code Playgroud)