一. 带定时器和锁的LRU缓存
#include <iostream>
#include <unordered_map>
#include <chrono>
#include <mutex>
#include <thread>
using namespace std;
class LRUCache {
public:
typedef struct Node {//双向链表节点
int key; // 在哈希中的键值,用于删除哈希
int data;
Node* pre;
Node* next;
chrono::steady_clock::time_point timestamp; // 时间戳,用于生存时间
Node() : key(0), data(0), pre(nullptr), next(nullptr), timestamp(chrono::steady_clock::now()) {}
Node(int key, int val) : key(key), data(val), pre(nullptr), next(nullptr), timestamp(chrono::steady_clock::now()) {}
}Node, *pNode;
int capacity;
unordered_map<int, pNode> m;
Node* listpre = new Node();
Node* listtail = new Node();
mutex mtx; // 并发访问锁
const chrono::seconds ttl = chrono::seconds(5); // 生存时间:5秒
LRUCache(int capacity) {
this->capacity = capacity;
listpre->next = listtail;
listtail->pre = listpre;
// 后台线程定期清理过期缓存
thread(&LRUCache::cleanUpExpired, this).detach();
}
void remove(Node* cur) {
Node* pre = cur->pre;
Node* next = cur->next;
pre->next = next;
next->pre = pre;
}
void update(Node* cur) {
remove(cur);
insert(cur);
cur->timestamp = chrono::steady_clock::now(); // 更新时间戳
}
void insert(Node* cur) {
listtail->pre->next = cur;
cur->pre = listtail->pre;
cur->next = listtail;
listtail->pre = cur;
}
void release() {
Node* cur = listpre->next;
m.erase(cur->key); // 删除哈希表中的键
remove(cur);
delete cur; // 释放内存
}
// 清理过期的缓存项
void cleanUpExpired() {
while (true) {
this_thread::sleep_for(chrono::seconds(1)); // 每1秒检查一次
lock_guard<mutex> lock(mtx); // 锁定访问
auto now = chrono::steady_clock::now();
Node* cur = listpre->next;
while (cur != listtail) {
if (chrono::duration_cast<chrono::seconds>(now - cur->timestamp) >= ttl) {
Node* next = cur->next;
m.erase(cur->key);
remove(cur);
delete cur;
cur = next;
} else {
cur = cur->next;
}
}
}
}
int get(int key) {
lock_guard<mutex> lock(mtx); // 加锁
if (m.count(key) == 0) return -1;
Node* cur = m[key];
if (chrono::duration_cast<chrono::seconds>(chrono::steady_clock::now() - cur->timestamp) >= ttl) {
// 缓存已过期,删除
m.erase(key);
remove(cur);
delete cur;
return -1;
}
update(cur); // 更新优先级
return cur->data;
}
void put(int key, int value) {
lock_guard<mutex> lock(mtx); // 加锁
if (m.count(key)) {
Node* cur = m[key];
cur->data = value;
update(cur);
return;
}
if (m.size() == capacity) release(); // 超出容量,释放最久未使用的节点
Node* cur = new Node(key, value);
m[key] = cur;
insert(cur);
}
};
二. 循环打印123
package main
import (
"fmt"
"sync"
)
func main() {
ch1 := make(chan bool)
ch2 := make(chan bool)
ch3 := make(chan bool)
bufferSize := 5
ch := make(chan int, bufferSize) // 创建一个带缓冲的通道
ch <- 1
var wg sync.WaitGroup
var mutex sync.Mutex
mutex.Lock()
defer mutex.Unlock()
wg.Add(3) // 每个 Goroutine 负责三次打印
// Goroutine 打印 1
go func() {
defer wg.Done() // 完成后标记 Done
for i := 0; i < 3; i++ { // 打印 3 次
<-ch1
fmt.Println(1)
ch2 <- true // 通知第二个 Goroutine
}
}()
// Goroutine 打印 2
go func() {
defer wg.Done() // 完成后标记 Done
for i := 0; i < 3; i++ { // 打印 3 次
<-ch2
fmt.Println(2)
ch3 <- true // 通知第三个 Goroutine
}
}()
// Goroutine 打印 3
go func() {
defer wg.Done() // 完成后标记 Done
for i := 0; i < 3; i++ { // 打印 3 次
<-ch3
fmt.Println(3)
if i < 2 { // 在前两次时继续循环
ch1 <- true // 通知第一个 Goroutine
}
}
}()
// 启动第一个 Goroutine
ch1 <- true
// 等待所有 Goroutine 完成
wg.Wait()
}
三. 单例模式
#include <iostream>
#include <mutex>
// 懒汉式单例模式 (Lazy Singleton)
class LazySingleton {
private:
static LazySingleton* instance; // 指向单例对象的指针
static std::mutex mtx; // 用于保证线程安全的互斥锁
// 私有化构造函数,禁止外部实例化
LazySingleton() {
std::cout << "LazySingleton Constructor Called" << std::endl;
}
public:
// 禁止拷贝构造函数和赋值操作符
LazySingleton(const LazySingleton&) = delete;
LazySingleton& operator=(const LazySingleton&) = delete;
// 静态方法,用于获取单例实例
static LazySingleton* getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx); // 线程安全锁
if (instance == nullptr) { // 双重检查锁定
instance = new LazySingleton();
}
}
return instance;
}
};
// 饿汉式单例模式 (Eager Singleton)
class EagerSingleton {
private:
// 静态实例在程序启动时立即创建
static EagerSingleton instance;
// 私有化构造函数,禁止外部实例化
EagerSingleton() {
std::cout << "EagerSingleton Constructor Called" << std::endl;
}
public:
// 禁止拷贝构造函数和赋值操作符
EagerSingleton(const EagerSingleton&) = delete;
EagerSingleton& operator=(const EagerSingleton&) = delete;
// 静态方法,用于获取单例实例
static EagerSingleton& getInstance() {
return instance;
}
};
// 懒汉式单例模式 - 使用 C++11 静态局部变量的线程安全初始化
class LazySingleton {
private:
// 私有化构造函数,防止外部创建实例
LazySingleton() {
std::cout << "LazySingleton Constructor Called" << std::endl;
}
public:
// 禁止拷贝构造函数和赋值操作符
LazySingleton(const LazySingleton&) = delete;
LazySingleton& operator=(const LazySingleton&) = delete;
// 提供静态方法获取单例实例
static LazySingleton& getInstance() {
static LazySingleton instance; // 静态局部变量,C++11后线程安全
return instance;
}
};
标签:Node,pre,常用,撕非,cur,int,next,算法,key
From: https://www.cnblogs.com/929code/p/18472460