提问者:小点点

如何为许多作者和许多读者(线程)添加和删除HashMap?


是否可以在不同步关键字的情况下解决此代码?

我们可以使用ConCurrentHashMap或更好的带有同步关键字的HashMap(用于方法)吗?
或者更好的带有同步关键字(用于方法)的ConCurrentHashMap(用于迭代)?

这是临界区代码,读取器线程获取统计信息并减少值时(如果值为零,则删除统计信息,但并行写入器线程可能会产生值)。如何正确解决这个问题?

     Statistic statistic = data.get(id);
        if (statistic != null) {
            statistic.dec();

            if (statistic.getValue() <= 0) {
                data.remove(id);
           }
public class Main {

    private static final Map<Long, Statistic> data = new ConcurrentHashMap<>();

    public static void main(String... args) throws IOException {
        new Thread(() -> todoRunInWriterThread(1L)).start();
        new Thread(() -> todoRunInReaderThread(1L)).start();

        System.in.read();
    }

    //Many writers write some statistics
    private static void todoRunInWriterThread(long id) { 
        Statistic statistic = data.get(id);
        if (statistic == null) {
            statistic = new Statistic();
            data.put(id, statistic);
        }

        statistic.inc();
    }

    //Many readers read statistic and decrement value, 
    //if statistic value is zero (remove statistic)
    private static void todoRunInReaderThread(long id) {
        Statistic statistic = data.get(id);
        if (statistic != null) {
            statistic.dec();

            if (statistic.getValue() <= 0) {
                data.remove(id);
            }
        }
    }

    public static class Statistic {
        private AtomicLong value = new AtomicLong(0);

        public long getValue() {
            return value.longValue();
        }

        public void inc() {
            value.incrementAndGet();
        }

        public void dec() {
            value.decrementAndGet();
        }
    }
}

共1个答案

匿名用户

我相信你应该使用ConCurrentHashMap。它在大多数情况下都有很好的性能,您的编写线程情况(get… check if null…put)可以使用ConCurrentHashMap#computeIfAbsend解决-

也请做一些关于如何并发HashMap工作的研究。它不是简单地为每个方法使用同步关键字。涉及到一些条带锁定,这对性能非常有好处