java - 这种内存计算的实现是否正确?

标签 java concurrency

我需要实现一个简单的通用包装器来进行计算内存,并且能够根据需要重置内存值。计算可能需要长时间运行,因此重置不应阻塞太长时间 - 理想情况下,它只是将当前状态标记为“脏”并返回。

这就是我所做的:

import java.util.concurrent.Callable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CachedValue<A> {
    private Callable<A> creator;
    private Lock computationLock = new ReentrantLock();
    private Lock resultLock = new ReentrantLock();
    private volatile A cached = null;
    private volatile boolean wasCleared = false;

    public CachedValue(Callable<A> creator) {
        this.creator = creator;
    }

    public A get() {
        if (cached != null) {
            return cached;
        } else {
            computationLock.lock();
            try {
                if (cached != null) {
                    return cached;
                } else {
                    while (true) {
                        wasCleared = false;
                        A computed = creator.call();
                        resultLock.lock();
                        try {
                            if (!wasCleared) {
                                cached = computed;
                                return cached;
                            }
                        } finally {
                            resultLock.unlock();
                        }
                    }
                }
            } finally {
                computationLock.unlock();
            }
        }
    }

    public void reset() {
        resultLock.lock();
        try {
            cached = null;
            wasCleared = true;
        } finally {
            resultLock.unlock();
        }
    }
}

它似乎有效,但我对并行编程没有期望,所以我可能错过了一些死锁或效率问题?

最佳答案

您必须保护 cachedwasCleared 变量,因为这些变量可以在 get 时使用一个线程的 reset 方法重置code> 从另一个线程调用的方法,该方法将在同一组变量上工作。

您可以在重置方法中使用相同的可重入锁:

public void reset() {
    lock.lock();
    try {
        cached = null;
        wasCleared = true;
    } finally {
         lock.unlock();
    }
}

关于java - 这种内存计算的实现是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28793434/

相关文章:

java - 多线程安全类

c# - 并发子结构是否需要并发?

c++ - 在 C++ 中,加载是否可以在获取操作下方滑动/存储可以在释放上方 float 吗?

java - 如果包装类已经是不可变的,为什么我们还需要 Atomic* 类?

java - 即使只有一个编写器线程, volatile 也会出现问题

java - Primefaces p :dataTable changing default value message "No records found."?

java - 如何删除实体列表

java urlconnection 不抛出 sockettimeoutexception

java - 字符串的switch语句

java - 本地tomcat服务器返回405 Method Not allowed