簡體   English   中英

在Java如何同步緩存讀寫操作

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

我正在努力在我的應用程序中使用 ArrayList 實現一個簡單的緩存。

我想同步緩存更新操作,同時更新緩存我不應該允許執行讀取操作。 所以一旦緩存更新完成,那么只有緩存應該允許讀取。

上下文管理器.java

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

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

配置管理器.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()。

您可以使用通過ReentrantReadWriteLock實例實現的ReadWriteLock接口來實現這一點。 這個class可以代表你在執行getIdsloadIds操作時獲取相應的鎖來讀寫case。 實際上,

ReadWriteLock 維護一對關聯的鎖,一個用於只讀操作,一個用於寫入。 只要沒有寫者,讀鎖可以同時被多個讀者線程持有。 寫鎖是獨占的。

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

基本上,您的loadIds應該在繼續其操作之前獲取寫鎖。 如果成功,它會立即獲取鎖並繼續計算; 否則它會阻塞相應的線程,直到獲得鎖或拋出 InterruptedException。

另一方面, getIds方法應該獲取讀鎖。 如果可用,當前線程立即獲得鎖的位置; 否則它會阻塞相應的線程,直到獲得鎖或拋出 InterruptedException。

上下文管理器.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();
    }
}

配置管理器.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