Java中如何同步缓存读写操作

问题描述 投票:0回答:1

我正在努力在我的应用程序中使用 ArrayList 实现一个简单的缓存。

我想同步缓存更新操作,在更新缓存时我不应该允许执行读取操作。所以一旦缓存更新完成,那么只有缓存应该允许读取。

ContextManager.java

public class ContextManager{
    private List<String> trashCanIds;
    public List<String> getIds() {
        return ids;
    }

    public void setIds(List<String> ids) {
        this.ids = ids;
    }
}

ConfigManager.java

public class ConfigManager{
    ContextManager ctxManager = new ContextManager();
    public synchronized List<String> loadIds() throws Exception {
        Utils utils = new Utils();
        List<String> listIds = null;
        String[] ids = utils.fetchIds();    
        if(Objects.nonNull(ids) && ids.length > 0) {
            listIds = new ArrayList<>(Arrays.asList(ids[0].split(",")));
        }
        ctxManager.setIds(idsList);
        return idsList;
    }
}

删除管理器.java

public class DeleteManager {
    ConfigManager configManager = new ConfigManager();
    configManager.loadIds();
}

测试管理器.java

public class TestManager {
    ContextManager contextManager = new ContextManager();
    contextManager.getIds();
}

在此代码中,我同步了 loadIds() 方法。

需要帮助,如何防止在 loadIds() 进行时读取 getIds()。

java arrays multithreading caching thread-synchronization
1个回答
2
投票

您可以通过使用

ReadWriteLock
界面来实现您的目标。具体来说,
ReentrantReadWriteLock
实施。该类可以通过在执行
getIds
loadIds
操作时获取相应的锁来处理您的读写情况。

ReadWriteLock 维护一对关联的锁,一个用于只读操作,一个用于写入操作。只要没有写入者,读取锁就可以由多个读取者线程同时持有。写锁是独占的。

基本上,

loadIds
应该在继续其操作之前获取写锁。如果成功,它立即获取锁,然后继续计算。如果没有,该方法将阻塞相应的线程,直到获得锁或抛出
InterruptedException

相反,

getIds
方法应该获取读锁。在这种情况下,如果锁可用,则当前线程获得锁并继续前进。否则,该方法会阻塞相应的线程,直到获得锁或抛出
InterruptedException

ContextManager.java

public class ContextManager{
    private List<String> trashCanIds;
    private ReadWriteLock lock;
    private Lock readLock;
    private Lock writeLock;

    public ContextManager(){
        lock = new ReentrantReadWriteLock(true);
        readLock = lock.readLock();
        writeLock = lock.writeLock();    
    }

    public List<String> getIds() {
        readLock.lock();
        try {
            List<String> tempTrashCanIds = new ArrayList(trashCanIds);
        } finally {
            readLock.unlock();
        }
        return tempTrashCanIds;
    }

    public void setIds(List<String> ids) {
        this.ids = ids;
    }

    public void readLock(){
        this.readLock.lock();
    }

    public void readUnlock(){
        this.readLock.unlock();
    }

    public void writeLock(){
        this.writeLock.lock();
    }

    public void writeUnlock(){
        this.writeLock.unlock();
    }
}

ConfigManager.java

public class ConfigManager{
    ContextManager ctxManager = new ContextManager();
    public List<String> loadIds() throws Exception {
        Utils utils = new Utils();
        List<String> listIds = null;
        String[] ids = utils.fetchIds();    
        if(Objects.nonNull(ids) && ids.length > 0) {
            listIds = new ArrayList<>(Arrays.asList(ids[0].split(",")));
        }

        ctxManager.writeLock();
        try {
            ctxManager.setIds(idsList);
        } finally {
            ctxManager.writeUnlock();
        }
        return idsList;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.