LRU 缓存实现
/ 定义LRUCache类
public class LRUCache {
// 内部静态类Node,代表双向链表中的节点
private static class Node {
int key, value; // 节点的键和值
Node prev, next; // 指向前一个和后一个节点的指针
// 构造函数初始化节点的键和值
Node(int k, int v) {
key = k;
value = v;
}
}
// 缓存的最大容量
private final int capacity;
// 双向链表的虚拟头尾节点,形成循环链表
private final Node dummy = new Node(0, 0);
// 用于快速查找节点的键值映射
private final Map<Integer, Node> keyToNode = new HashMap<>();
// 构造函数,初始化LRUCache实例
public LRUCache(int capacity) {
this.capacity = capacity;
// 初始化双向链表,头尾节点指向自身
dummy.prev = dummy;
dummy.next = dummy;
}
// 获取操作,返回指定键的值或-1(未找到)
public int get(int key) {
Node node = getNode(key); // 尝试获取节点
return node != null ? node.value : -1; // 如果找到,返回值;否则返回-1
}
// 插入/更新操作,设置指定键的值
public void put(int key, int value) {
Node node = getNode(key); // 尝试获取节点
// 如果节点存在,则更新其值,并将其移动到链表头部
if (node != null) {
node.value = value;
return;
}
// 创建新节点
node = new Node(key, value);
// 将新节点添加到哈希表
keyToNode.put(key, node);
// 将新节点插入链表头部
pushFront(node);
// 如果超过最大容量,移除链表尾部的节点
if (keyToNode.size() > capacity) {
Node backNode = dummy.prev; // 获取链表尾部节点
keyToNode.remove(backNode.key); // 移除哈希表中的对应项
remove(backNode); // 从链表中移除节点
}
}
// 私有方法,用于获取节点并将其移动到链表头部
private Node getNode(int key) {
// 如果键不在哈希表中,直接返回null
if (!keyToNode.containsKey(key)) {
return null;
}
Node node = keyToNode.get(key); // 从哈希表中获取节点
// 移除节点
remove(node);
// 将节点插入链表头部
pushFront(node);
// 返回节点
return node;
}
// 私有方法,用于从链表中移除指定节点
private void remove(Node x) {
// 更新前驱和后继节点的指针,移除节点
x.prev.next = x.next;
x.next.prev = x.prev;
}
// 私有方法,用于将节点插入到链表头部
private void pushFront(Node x) {
// 设置新节点的前后指针
x.prev = dummy;
x.next = dummy.next;
// 更新链表头部节点的前后指针
x.prev.next = x;
x.next.prev = x;
}
}
用 Java 实现栈
public class StackImpl {
private int capacity; // 栈的最大容量
private int[] stack; // 用于存储栈元素的数组
private int top; // 栈顶指针,初始值为 -1,表示空栈
// 构造函数,初始化栈的大小和栈顶指针
public StackImpl(int maxSize) {
capacity = maxSize;
stack = new int[capacity];
top = -1;
}
// 弹出栈顶元素,若栈为空抛出异常
public int pop() {
if (top == -1) {
throw new EmptyStackException();
}
int key = stack[top];
top--;
return key;
}
// 入栈操作,若栈满抛出异常
public void push(int k) {
if (top < capacity - 1) {
top++;
stack[top] = k;
} else {
throw new IllegalStateException("Stack is full");
}
}
// 查看栈顶元素,若栈为空抛出异常
public int peek() {
if (top == -1) {
throw new EmptyStackException();
}
return stack[top];
}
// 判断栈是否为空
public boolean isEmpty() {
return top == -1;
}
// 主方法,用于测试栈的功能
public static void main(String[] args) {
StackImpl stack1 = new StackImpl(10); // 创建一个容量为10的栈
stack1.push(1);
stack1.push(2);
stack1.pop(); // 弹出栈顶元素,现在栈顶元素为1
if (!stack1.isEmpty()) { // 检查栈是否为空
System.out.println(stack1.peek()); // 安全地调用peek方法,输出栈顶元素1
} else {
System.out.println("Stack is empty.");
}
}
}
加权轮询算法的实现
加权轮询算法(Weighted Round Robin,WRR)是一种调度算法,常用于负载均衡、任务调度等场景。在WRR中,每个实体都有一个权重,调度时按照权重分配调用的频率或时间间隔。下面是一个简单的加权轮询算法的Java实现,我们假设要调度的对象是一个列表,列表中的每个对象都有一个权重。
public class Scheduler {
private List<WeightObject> weightObjects;
private Queue<WeightObject> queue;
private int currentWeight;
public Scheduler(List<WeightObject> weightObjects)
{
this.weightObjects=weightObjects;
this.queue=new LinkedList<WeightObject>();
this.currentWeight=0;
initScheduler();
}
public void initScheduler()
{
for(WeightObject obj:weightObjects)
{
for(int i=0;i<obj.getWeights();i++)
{
queue.add(obj);
}
}
}
public synchronized WeightObject getNext()
{
if(queue.isEmpty())
{
initScheduler();
}
WeightObject weightObject=queue.poll();
currentWeight+=weightObject.getWeights();
return weightObject;
}
public int getCurrentWeight() {
return currentWeight;
}
public static <WeightedObject> void main(String[] args) {
List<WeightObject> objects = new LinkedList<>();
objects.add(new WeightObject("A", 2));
objects.add(new WeightObject("B", 1));
objects.add(new WeightObject("C", 3));
Scheduler scheduler = new Scheduler(objects);
for (int i = 0; i < 100; i++) {
WeightObject obj = scheduler.getNext();
System.out.println("Selected: " + obj.getName());
}
}
}
class WeightObject
{
private String name;
private int weights;
public WeightObject(String name, int weights) {
this.name = name;
this.weights = weights;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWeights() {
return weights;
}
public void setWeights(int weights) {
this.weights = weights;
}
}
死锁现象
public class DeadLock {
private final Lock lock1 = new ReentrantLock();
private final Lock lock2 = new ReentrantLock();
public void printA()
{
lock1.lock();
System.out.println(Thread.currentThread().getName()+"线程A获取锁1");
try
{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"线程A尝试获取锁2");
lock2.lock();
System.out.println(Thread.currentThread().getName()+"线程A得到锁2");
}
catch (Exception e)
{
Thread.interrupted();
}
finally {
lock2.unlock();
lock1.unlock();
}
}
public void printB()
{
lock2.lock();
System.out.println(Thread.currentThread().getName()+"线程B获取锁2");
try
{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"线程B尝试获取锁1");
lock1.lock();
System.out.println(Thread.currentThread().getName()+"线程B得到锁1");
}
catch (Exception e)
{
Thread.interrupted();
}
finally {
lock1.unlock();
lock2.unlock();
}
}
public static void main(String[] args) {
DeadLock deadLock =new DeadLock();
Thread thread1=new Thread(deadLock::printA, "a");
Thread thread2=new Thread(deadLock::printB, "B");
thread1.start();
thread2.start();
try
{
thread1.join();
thread2.join();
}catch (Exception e)
{
Thread.interrupted();
}
}
}