简体   繁体   English

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

[英]In Java how to synchronize cache read and write operations

I am working on implementing a simple cache using ArrayList in my application.我正在努力在我的应用程序中使用 ArrayList 实现一个简单的缓存。

I would like to synchronize cache update operations, while updating the cache I should not allow to perform read operations.我想同步缓存更新操作,同时更新缓存我不应该允许执行读取操作。 So once cache update is completed, then only cache should allow to read.所以一旦缓存更新完成,那么只有缓存应该允许读取。

ContextManager.java上下文管理器.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配置管理器.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;
    }
}

DeleteManager.java删除管理器.java

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

TestManager.java测试管理器.java

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

In this code I have synchronized the loadIds() method.在这段代码中,我同步了 loadIds() 方法。

Need help, how to prevent reading getIds() while loadIds() in progress.需要帮助,如何防止在 loadIds() 进行时读取 getIds()。

You could achieve this by using the ReadWriteLock interface implemented with a ReentrantReadWriteLock instance.您可以使用通过ReentrantReadWriteLock实例实现的ReadWriteLock接口来实现这一点。 This class can represent your case of read and write by acquiring the corresponding lock when performing the getIds and loadIds operations.这个class可以代表你在执行getIdsloadIds操作时获取相应的锁来读写case。 In fact,实际上,

A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. ReadWriteLock 维护一对关联的锁,一个用于只读操作,一个用于写入。 The read lock may be held simultaneously by multiple reader threads, so long as there are no writers.只要没有写者,读锁可以同时被多个读者线程持有。 The write lock is exclusive.写锁是独占的。

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html

Basically, your loadIds should acquire the write-lock before proceeding with its operations.基本上,您的loadIds应该在继续其操作之前获取写锁。 If it succeeds, it immediately acquires the lock and carries on with its computation;如果成功,它会立即获取锁并继续计算; otherwise it blocks the corresponding thread until the lock is obtained or an InterruptedException is thrown.否则它会阻塞相应的线程,直到获得锁或抛出 InterruptedException。

On the other hand, the getIds method should acquire the read-lock instead.另一方面, getIds方法应该获取读锁。 Where the current thread immediately obtains the lock if this is available;如果可用,当前线程立即获得锁的位置; otherwise it blocks the corresponding thread until the lock is obtained or an InterruptedException is thrown.否则它会阻塞相应的线程,直到获得锁或抛出 InterruptedException。

ContextManager.java上下文管理器.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配置管理器.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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM