Java 实现 FIFO 缓存算法

一、什么是 FIFO

FIFOFirst In, First Out)是一种常见的数据结构,也叫做先进先出队列。它的特点是先进入队列的数据最先出队。
类似于现实中排队买东西的场景,先来的人先排队,先买完商品的人先离开。

在计算机领域,FIFO 常用于缓存管理、进程调度等场景中。
在缓存管理中,先进入缓存的数据将被优先保留,后进入的数据会被淘汰;在进程调度中,先进入队列等待CPU资源的进程将先被分配到CPU运行。


二、Java 实现 FIFO 算法

1、方案1

import java.util.LinkedList;

public class FIFOQueue<T> {
    
    
    private final LinkedList<T> queue = new LinkedList<T>();
    private final int maxSize;

    public FIFOQueue(int maxSize) {
    
    
        this.maxSize = maxSize;
    }

    public void add(T item) {
    
    
        if (queue.size() >= maxSize) {
    
    
            queue.removeFirst();
        }
        queue.addLast(item);
    }

    public T remove() {
    
    
        return queue.removeFirst();
    }

    public boolean isEmpty() {
    
    
        return queue.isEmpty();
    }

    public int size() {
    
    
        return queue.size();
    }

    public T peek() {
    
    
        return queue.peek();
    }
}

上述代码使用 LinkedList 作为底层实现,定义了一个 FIFOQueue 类,支持元素添加、删除、判断队列是否为空、获取队列长度以及获取队头元素等操作。
其中,maxSize 为队列的最大容量,当队列元素数量达到最大容量时,再添加新的元素时会将最早加入的元素移除。
这里使用了 LinkedList 的 removeFirst() 方法和 addLast() 方法,保证队头元素是最早加入队列的元素。

使用示例:

public class Test {
    
    
    public static void main(String[] args) {
    
    
        FIFOQueue<String> queue = new FIFOQueue<>(5);
        queue.add("a");
        queue.add("b");
        queue.add("c");
        System.out.println(queue.remove()); // 输出:a
        System.out.println(queue.peek()); // 输出:b
        System.out.println(queue.size()); // 输出:2
        queue.add("d");
        queue.add("e");
        queue.add("f");
        System.out.println(queue.remove()); // 输出:b
    }
}

上述代码演示了如何创建一个FIFOQueue对象,添加、删除元素以及获取队列状态信息等操作。
其中,先添加的元素"a"最先出队,后添加的元素"f"最后出队。


2、方案2

import java.util.LinkedList;

public class FIFOCache<K, V> {
    
    
    private final int capacity;
    private final LinkedList<K> keyList;
    private final Map<K, V> cacheMap;

    public FIFOCache(int capacity) {
    
    
        this.capacity = capacity;
        this.keyList = new LinkedList<>();
        this.cacheMap = new HashMap<>();
    }

    public synchronized void put(K key, V value) {
    
    
        if (keyList.size() == capacity) {
    
    
            K removedKey = keyList.removeFirst();
            cacheMap.remove(removedKey);
        }
        keyList.addLast(key);
        cacheMap.put(key, value);
    }

    public synchronized V get(K key) {
    
    
        return cacheMap.get(key);
    }
}

在上述代码中,使用了 Java 的 LinkedList 类来维护一个按照顺序的 key 列表,并通过 Java 的 Map 接口实现了缓存的 key-value 存储。
当缓存满时,删除队列中最早的元素,并从缓存中删除相应的键值对。当获取缓存值时,直接从缓存中获取相应的值。

需要注意的是,在多线程环境下,需要加上 synchronized 关键字来保证线程安全。
同时,由于 LinkedList 和 HashMap 的实现不是线程安全的,因此在多线程环境下,还需要使用线程安全的集合类来代替它们。


猜你喜欢

转载自blog.csdn.net/aikudexiaohai/article/details/130679856