我有一个Java REST应用程序,其中一个端点始终处理ConcurrentMap。我正在进行负载测试,当负载测试开始增加时,这确实很糟糕。

我可以实施哪些策略来提高应用程序的效率?

我应该使用Jetty线程吗,因为它是我正在使用的服务器?还是主要是代码?或两者?

成为瓶颈的方法如下。

基本上,我需要从给定文件中读取一些行。我无法将其存储在数据库中,因此我通过Map进行了此处理。但是,我知道对于大文件,不仅要花很长时间才能到达该行,而且我冒这样一个事实,即Map包含许多条目时会占用大量内存...

dictConcurrentMap

public String getLine(int lineNr) throws IllegalArgumentException {
    if (lineNr > nrLines) {
        throw new IllegalArgumentException();
    }

    if (dict.containsKey(lineNr)) {
        return dict.get(lineNr);
    }

    synchronized (this) {
        try (Stream<String> st = Files.lines(doc.toPath())

            Optional<String> optionalLine = st.skip(lineNr - 1).findFirst();

            if (optionalLine.isPresent()) {
                dict.put(lineNr, optionalLine.get());
            } else {
                nrLines = nrLines > lineNr ? lineNr : nrLines;
                throw new IllegalArgumentException();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return cache.get(lineNr);
    }

最佳答案

ConcurrentMapsynchronized(this)混合可能不是正确的方法。 java.util.concurrent包中的类是为特定用例设计的,并尝试在内部优化同步。

相反,我建议先尝试一个设计良好的缓存库,看看性能是否足够好。一个示例是Caffeine。根据Population文档,它为您提供了一种声明如何加载数据的方法,甚至是异步的:

AsyncLoadingCache<Key, Graph> cache = Caffeine.newBuilder()
    .maximumSize(10_000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    // Either: Build with a synchronous computation that is wrapped as asynchronous
    .buildAsync(key -> createExpensiveGraph(key));
    // Or: Build with a asynchronous computation that returns a future
    .buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));

07-28 02:45