Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.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 如何为多个编写器和多个读卡器(线程)添加和删除HashMap?_Java_Thread Safety_Concurrenthashmap - Fatal编程技术网

Java 如何为多个编写器和多个读卡器(线程)添加和删除HashMap?

Java 如何为多个编写器和多个读卡器(线程)添加和删除HashMap?,java,thread-safety,concurrenthashmap,Java,Thread Safety,Concurrenthashmap,是否可以在没有关键字同步的情况下解决此代码 我们可以使用ConcurrentHashMap或更好的HashMap和同步关键字作为方法吗? 还是更好的ConcurrentHashMap,用于使用同步关键字进行迭代 这是关键段代码,读线程获得统计信息,当值为零时,减少值,删除统计信息,但并行写线程可能会增加值。如何妥善解决这一问题? Statistic statistic = data.get(id); if (statistic != null) {

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

我们可以使用ConcurrentHashMap或更好的HashMap和同步关键字作为方法吗? 还是更好的ConcurrentHashMap,用于使用同步关键字进行迭代

这是关键段代码,读线程获得统计信息,当值为零时,减少值,删除统计信息,但并行写线程可能会增加值。如何妥善解决这一问题?

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

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

我认为您应该使用ConcurrentHashMap。它在大多数情况下都有很好的性能,而你的writer线程的情况得到了。。。检查是否为空。。。put可以通过ConcurrentHashMapcomputeIfAbsent->解决,它将在内部处理所有锁定


另外,请研究一下ConcurrentHashMap是如何工作的。它不是简单地为每个方法使用synchronized关键字。这里涉及到一些条带锁定,这对性能非常好

好的,我不理解ComputeFabSent用于添加新对象,computeIfPresent用于删除对象。ConcurrentHashMap有助于提高性能。谢谢
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();
        }
    }
}