Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java字典-为字符串指定int值_Java_Map_Concurrency_Performance - Fatal编程技术网

Java字典-为字符串指定int值

Java字典-为字符串指定int值,java,map,concurrency,performance,Java,Map,Concurrency,Performance,如果这看起来是一个简单的问题,很抱歉,但我需要存储6000万条记录,其中总共包含200万个不同的字符串。在6000万条记录中,我想存储字符串的整数表示形式,因此在加载记录时,我将为它们分配一个整数 e、 g。 如果我的输入是a、b、c、a 然后我将存储1,2,3,1 记录将在多个线程中读取和提交。从线程和效率的角度来看,我提出了以下几点,我能做些什么改进吗 编辑:我将建立地图,有多达200万关键点。如果我不这样做,我将不得不使用字符串。我正在使用Trove的TIntHashMap和下面的方法,我

如果这看起来是一个简单的问题,很抱歉,但我需要存储6000万条记录,其中总共包含200万个不同的字符串。在6000万条记录中,我想存储字符串的整数表示形式,因此在加载记录时,我将为它们分配一个整数

e、 g。 如果我的输入是a、b、c、a 然后我将存储1,2,3,1

记录将在多个线程中读取和提交。从线程和效率的角度来看,我提出了以下几点,我能做些什么改进吗

编辑:我将建立地图,有多达200万关键点。如果我不这样做,我将不得不使用字符串。我正在使用Trove的TIntHashMap和下面的方法,我得到了更好的性能

非常感谢,

private final Map<String, Integer> stringDictionary = new HashMap<>(2000000);

private int index = 0;

private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

public int getStringCodeIntegerValue(String stringCode) {
    readWriteLock.readLock().lock();
    Integer result = stringDictionary.get(stringCode);
    if (result == null) {
        // Must release read lock before acquiring write lock
        readWriteLock.readLock().unlock();
        readWriteLock.writeLock().lock();
        try {
            result = stringDictionary.get(stringCode);
            if (result == null) {
                stringDictionary.put(stringCode, ++index);
                result = stringDictionary.get(stringCode);
            }
            // Downgrade by acquiring read lock before releasing write lock
            readWriteLock.readLock().lock();
        } finally {
            readWriteLock.writeLock().unlock(); // Unlock write, still hold read
        }
    }
    readWriteLock.readLock().unlock();
    return result;
}
private final Map stringDictionary=新HashMap(2000000);
私有整数指数=0;
private final ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
public int getStringCodeIntegerValue(字符串stringCode){
readWriteLock.readLock().lock();
整数结果=stringDictionary.get(stringCode);
如果(结果==null){
//在获取写锁之前必须释放读锁
readWriteLock.readLock().unlock();
readWriteLock.writeLock().lock();
试一试{
结果=stringDictionary.get(stringCode);
如果(结果==null){
stringDictionary.put(stringCode,++索引);
结果=stringDictionary.get(stringCode);
}
//通过在释放写锁之前获取读锁来降级
readWriteLock.readLock().lock();
}最后{
readWriteLock.writeLock().unlock();//解锁写入,仍保持读取
}
}
readWriteLock.readLock().unlock();
返回结果;
}

首先,听起来好像你在尝试重新设计内部字符串?您有什么理由不能使用作为问题标准的插入字符串吗

其次,如果您确实需要自己执行此操作,而不是在
HashMap
之上分层您自己的锁定策略,那么您最好使用它,它为多个并发编写器提供支持

为了回答您在评论中提出的问题,这里尝试实现
getStringCodeIntegerValue
(未经测试,但我有理由相信它是正确的,
putIfAbsent
的功能几乎正是您想要的):

最终AtomicInteger索引=新的AtomicInteger();
final ConcurrentHashMap stringDictionary=新ConcurrentHashMap();
public int getStringCodeIntegerValue(字符串stringCode){
整数结果=stringDictionary.get(stringCode);
如果(结果!=null)
返回结果;
其他的
返回stringDictionary.putIfAbsent(stringCode,index.incrementAndGet());
}
如果两个线程都试图同时添加相同的字符串,这个实现可能会导致索引值被“丢弃”,但我不认为这对您来说是个问题

综上所述,如果您已经根据标准映射测试了您的实现,并且它的性能更好,那么这就表明,
stringDictionary
的并发更新对于您的特定使用模式来说并不是问题,所以也许您应该坚持您已经得到的


话虽如此,在我看来,这仍然像是你在试图重新创造实习弦乐。为什么你不能使用实习字符串呢?它们听起来正是我所需要的?

读了你的评论后,我仍然不清楚你想要实现什么

但是,您可以生成字符串的整数摘要(字符串可以是任意长度)。例如SHA1或MD5。您可以使用apachecommons来实现这一点

然后可以为每个字符串存储摘要和物理字符串,但是拥有SHA1/MD5列将帮助您按摘要索引数据并更快地访问记录

请记住,摘要是不可逆的,即不能从摘要中复制原始字符串


希望有帮助

为什么要整数而不是字符串?您将如何使用存储的数据?(您需要快速读取/写入/搜索等吗?@aviad Hi,我需要根据记录构建许多阵列组合,它们的长度将高达500万。使用integer是从内存优化的角度出发的。我想说我的字符串的平均长度大约是30个字符。关于使用基本映射而不是java自己的映射,请参见我的编辑。另外,如果我使用ConcurrentHashMap,我该如何处理该值不存在的情况,因此我需要增加计数器,插入新值并返回它?我注意到您已经就此提出了5个问题,并且只接受了一个答案。如果你接受答案(或说明为什么答案不被接受),你将增加收到未来问题答案的机会。
final AtomicInteger index = new AtomicInteger();
final ConcurrentHashMap<String, Integer> stringDictionary = new ConcurrentHashMap<String, Integer>();

public int getStringCodeIntegerValue(String stringCode) {
    Integer result = stringDictionary.get(stringCode);
    if (result != null)
        return result;
    else
        return stringDictionary.putIfAbsent(stringCode, index.incrementAndGet());
}