Java 更新键/值的集合不会提供所需的性能

Java 更新键/值的集合不会提供所需的性能,java,multithreading,concurrency,Java,Multithreading,Concurrency,我在集合对象中存储了大量记录,作为键值对。我想使用线程,我想迭代集合,进行restfull调用,更新集合对象中的值 我看到多个线程访问相同的键值对并更新相同的记录。这并没有给我想要的表现。 请找个人帮忙你需要澄清你的问题。 看起来您正在尝试更新集合上的值,并且希望通过使用多个线程来加快更新过程,但是您需要每个线程选择不同的键,而现在不同的线程正在选择相同的键,这使得更新过程效率低下 首先,您的API中存在一个设计问题,您应该能够使用多个键进行一次调用,以便在对API的一次调用中更新所有键。为每个

我在集合对象中存储了大量记录,作为键值对。我想使用线程,我想迭代集合,进行restfull调用,更新集合对象中的值

我看到多个线程访问相同的键值对并更新相同的记录。这并没有给我想要的表现。
请找个人帮忙

你需要澄清你的问题。 看起来您正在尝试更新集合上的值,并且希望通过使用多个线程来加快更新过程,但是您需要每个线程选择不同的键,而现在不同的线程正在选择相同的键,这使得更新过程效率低下

首先,您的API中存在一个设计问题,您应该能够使用多个键进行一次调用,以便在对API的一次调用中更新所有键。为每个键调用api本身就是一种性能开销

其次,如果希望确保线程选择不同的键,则需要使用不同的数据结构,如队列,然后每个线程将从队列中弹出一个值,并更新该键

当您的项目需要非常高的并发性时,应该使用ConcurrentHashMap。 它是线程安全的,无需同步整个映射。 当使用锁完成写入时,读取可以非常快地发生。 在对象级别没有锁定。 在hashmap bucket级别,锁定的粒度要细得多。 如果一个线程试图修改ConcurrentHashMap,而另一个线程正在对其进行迭代,则ConcurrentHashMap不会抛出ConcurrentModificationException。 ConcurrentHashMap使用大量锁。 代码示例:


请添加代码示例,并指定您使用的是集合还是映射。您是否关心性能或预期结果?您的问题听起来好像不希望多个线程更新同一条记录。这并不能提供问题的答案。一旦你有足够的钱,你将能够;相反@Shawn Mehan作为一个做过大量线程编程的人,我相信如果OP实现了这个答案中的建议,问题就会消失,因此,我相信这是一个答案。它确实正确地指出了这个问题可以改进,但它确实继续回答了这个问题。根据您的观察,您是对的,而我不得不多次调用API,以获取键的值,您建议使用Que,因为解决方案看起来很适合我。我也会试试,然后再回来找你。。非常感谢你的建议谢谢,我会在你给我的样本中尝试一下。
public class ConcurrentHashMapSample {

    public final static int THREAD_POOL_SIZE = 5;
    public static Map<String, Integer> concurrentHashMap;

    public static void main(String[] args) throws InterruptedException {
        concurrentHashMap = new ConcurrentHashMap<String, Integer>();
        performTest(concurrentHashMap);
    }

    public static void performTest(final Map<String, Integer> concurrentHashMap) throws InterruptedException {
        long averageTime = 0;
        for (int i = 0; i < 5; i++) {
            long startTime = System.nanoTime();
            ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
            for (int j = 0; j < THREAD_POOL_SIZE; j++) {
                executorService.execute(new Runnable() {
                    @SuppressWarnings("unused")
                    @Override
                    public void run() {
                        for (int i = 0; i < 500000; i++) {
                            Integer randomNumber = (int) Math.ceil(Math.random() * 550000);
                            Integer value = concurrentHashMap.get(String.valueOf(randomNumber));
                            concurrentHashMap.put(String.valueOf(randomNumber), randomNumber);
                        }
                    }
                });
            }

            // Make sure executor stops
            executorService.shutdown();

            // Blocks until all tasks have completed execution after a shutdown request
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

            long entTime = System.nanoTime();
            long totalTime = (entTime - startTime) / 1000000L;
            averageTime += totalTime;
            System.out.println("2500K entried added/retrieved in " + totalTime + " ms");
        }
        System.out.println("For " + concurrentHashMap.getClass() + " the average time is " + averageTime / 5 + " ms\n");
    }
}