一. 带定时器和锁的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;
}
};
四. 工厂模式
#include <iostream>
#include <memory> // for std::unique_ptr
// 产品基类
class Product {
public:
virtual void show() const = 0;
virtual ~Product() = default;
};
// 具体产品A
class ProductA : public Product {
public:
void show() const override {
std::cout << "This is Product A." << std::endl;
}
};
// 具体产品B
class ProductB : public Product {
public:
void show() const override {
std::cout << "This is Product B." << std::endl;
}
};
// 工厂类
class Factory {
public:
std::unique_ptr<Product> createProduct(const std::string& type) {
if (type == "A") {
return std::make_unique<ProductA>();
} else if (type == "B") {
return std::make_unique<ProductB>();
} else {
return nullptr;
}
}
};
int main() {
Factory factory;
// 创建产品 A
std::unique_ptr<Product> productA = factory.createProduct("A");
if (productA) productA->show();
// 创建产品 B
std::unique_ptr<Product> productB = factory.createProduct("B");
if (productB) productB->show();
return 0;
}
五. 观察者模式
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
// 观察者接口
class Observer {
public:
virtual void update(const std::string& message) = 0;
virtual ~Observer() = default;
};
// 具体观察者1
class ConcreteObserver1 : public Observer {
public:
void update(const std::string& message) override {
std::cout << "ConcreteObserver1 received: " << message << std::endl;
}
};
// 具体观察者2
class ConcreteObserver2 : public Observer {
public:
void update(const std::string& message) override {
std::cout << "ConcreteObserver2 received: " << message << std::endl;
}
};
// 被观察者(发布者)
class Subject {
public:
void attach(std::shared_ptr<Observer> observer) {
observers.push_back(observer);
}
void detach(std::shared_ptr<Observer> observer) {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify(const std::string& message) {
for (const auto& observer : observers) {
observer->update(message);
}
}
private:
std::vector<std::shared_ptr<Observer>> observers;
};
int main() {
Subject subject;
std::shared_ptr<Observer> observer1 = std::make_shared<ConcreteObserver1>();
std::shared_ptr<Observer> observer2 = std::make_shared<ConcreteObserver2>();
// 添加观察者
subject.attach(observer1);
subject.attach(observer2);
// 被观察者状态发生变化,通知所有观察者
subject.notify("State has changed!");
// 移除观察者1
subject.detach(observer1);
// 再次通知,只有 observer2 会收到消息
subject.notify("Another update!");
return 0;
}
六. 智能指针
#include <iostream>
#include <mutex>
template <typename T>
class SafeUniquePtr {
public:
// 构造函数:接受一个原始指针
explicit SafeUniquePtr(T* ptr = nullptr) : pointer(ptr) {}
// 禁用拷贝构造和拷贝赋值
SafeUniquePtr(const SafeUniquePtr&) = delete;
SafeUniquePtr& operator=(const SafeUniquePtr&) = delete;
// 移动构造函数
SafeUniquePtr(SafeUniquePtr&& other) {
std::lock_guard<std::mutex> lock(other.mtx);
pointer = other.pointer;
other.pointer = nullptr;
}
// 移动赋值操作符
SafeUniquePtr& operator=(SafeUniquePtr&& other) {
if (this != &other) {
std::lock_guard<std::mutex> lock1(mtx);
std::lock_guard<std::mutex> lock2(other.mtx);
delete pointer;
pointer = other.pointer;
other.pointer = nullptr;
}
return *this;
}
// 解引用操作符
T& operator*() {
std::lock_guard<std::mutex> lock(mtx);
return *pointer;
}
// 指针访问操作符
T* operator->() {
std::lock_guard<std::mutex> lock(mtx);
return pointer;
}
// 释放资源
~SafeUniquePtr() {
std::lock_guard<std::mutex> lock(mtx);
delete pointer;
}
private:
T* pointer; // 原始指针
mutable std::mutex mtx; // 用于保护指针的互斥锁
};
七. 事务和分布式事务
BEGIN; -- 开启事务
-- 检查 A 表中的余额是否足够
UPDATE A
SET balance = balance - 100
WHERE user_id = 1
AND balance >= 100;
-- 检查余额更新是否成功(即 A 表的余额是否足够)
IF ROW_COUNT() = 0 THEN
-- 如果没有行受到影响,说明余额不足,回滚事务
ROLLBACK;
-- 余额不足处理
SELECT '余额不足';
ELSE
-- 如果余额足够,继续进行 B 表的更新
UPDATE B
SET balance = balance + 100
WHERE user_id = 2;
-- 提交事务
COMMIT;
END IF;
-- 数据库 1:检查余额并准备扣款
START TRANSACTION;
UPDATE A
SET balance = balance - 100
WHERE user_id = 1
AND balance >= 100;
-- 检查是否扣款成功
IF ROW_COUNT() = 0 THEN
-- 余额不足,回滚事务
ROLLBACK;
-- 向协调者报告失败
REPORT FAILURE TO COORDINATOR;
ELSE
-- 准备事务但不提交
PREPARE TRANSACTION 'txn1';
-- 向协调者报告准备完成
REPORT SUCCESS TO COORDINATOR;
END IF;
-- 数据库 2:准备增加余额
START TRANSACTION;
UPDATE B
SET balance = balance + 100
WHERE user_id = 2;
PREPARE TRANSACTION 'txn2';
-- 如果协调者收到两个数据库的成功报告,则提交事务
COMMIT PREPARED 'txn1';
COMMIT PREPARED 'txn2';