如何让C++14中的简单工厂方法实现线程安全?
问题:C++14中为简单工厂方法实现线程同步保护
我有如下C++简单工厂方法代码:
class Vehicle { public: virtual void printVehicle() = 0; static Vehicle* Create(VehicleType type); virtual ~Vehicle(){} }; Vehicle* Vehicle::Create(VehicleType type) { if (type == VT_TwoWheeler) return new TwoWheeler(); else if (type == VT_ThreeWheeler) return new ThreeWheeler(); else if (type == VT_FourWheeler) return new FourWheeler(); else return NULL; }
希望该工厂方法在多线程调用时受到保护,仅向调用线程返回新对象,其他线程等待。在Java中我知道可以用如下方式实现:
synchronized (Vehicle .class) { .. protected code ... }
请问如何在C++14中实现这一需求?
解决方案
在C++14中,你可以通过类级别的静态互斥锁配合RAII锁工具来实现和Java类锁一致的线程同步效果,具体实现如下:
步骤1:添加静态互斥锁成员
在Vehicle类中定义一个静态的std::mutex对象,它属于整个类,所有线程共享,对应Java中的类锁逻辑。
步骤2:使用RAII锁管理工具保护代码块
用std::lock_guard(或std::unique_lock)来自动管理锁的加锁和解锁,避免手动操作锁导致的遗漏或异常安全问题。
修改后的完整代码
#include <mutex> // 补充原代码缺失的枚举和子类实现 enum VehicleType { VT_TwoWheeler, VT_ThreeWheeler, VT_FourWheeler }; class TwoWheeler : public Vehicle { public: void printVehicle() override { /* 自定义实现 */ } }; class ThreeWheeler : public Vehicle { public: void printVehicle() override { /* 自定义实现 */ } }; class FourWheeler : public Vehicle { public: void printVehicle() override { /* 自定义实现 */ } }; class Vehicle { public: virtual void printVehicle() = 0; static Vehicle* Create(VehicleType type); virtual ~Vehicle(){} private: static std::mutex create_mutex; // 类级别的静态互斥锁 }; // 必须在类外初始化静态互斥锁 std::mutex Vehicle::create_mutex; Vehicle* Vehicle::Create(VehicleType type) { // std::lock_guard构造时自动加锁,函数结束时自动解锁 std::lock_guard<std::mutex> lock(create_mutex); if (type == VT_TwoWheeler) return new TwoWheeler(); else if (type == VT_ThreeWheeler) return new ThreeWheeler(); else if (type == VT_FourWheeler) return new FourWheeler(); else return nullptr; // 推荐用C++11引入的nullptr替代NULL }
关键说明
- 静态互斥锁:
std::mutex Vehicle::create_mutex是类的静态成员,所有线程共享,确保同一时间只有一个线程能进入Create方法的临界区。 - RAII锁管理:
std::lock_guard是轻量级RAII工具,无需手动调用lock()和unlock(),即使函数因异常退出,也能保证锁被正确释放,避免死锁。 - 效果等价性:这种实现和Java的
synchronized(Vehicle.class)完全等价,都能实现类级别的线程同步,保证同一时间只有一个线程执行受保护的代码逻辑。
如果需要更灵活的锁控制(比如中途解锁、尝试加锁),可以替换为std::unique_lock<std::mutex>,但对于当前场景,std::lock_guard是最简洁高效的选择。
内容的提问来源于stack exchange,提问作者user63898
相关产品推荐
相关产品推荐

