如何实现带构造析构的线程安全计数式单例?多线程场景适配
泛型服务管理器设计方案
核心解决思路
- 用线程安全的全局映射容器按服务名称共享状态(计数器+服务实例),避免每个对象单独维护计数导致的重复启停
- 计数器用原子类保证多线程下的增减操作原子性,防止并发计数错误
start时仅当计数器从0变为1时启动底层服务;stop时仅当计数器从1变为0时停止服务,同时清理状态
Java泛型实现示例
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; public class NamedServiceManager<T> { // 存储每个服务名称对应的状态:引用计数+服务实例 private final ConcurrentHashMap<String, ServiceState<T>> serviceStates = new ConcurrentHashMap<>(); // 服务工厂,负责创建具体的底层服务实例 private final ServiceFactory<T> serviceFactory; // 服务工厂接口,解耦服务创建逻辑 public interface ServiceFactory<T> { T createService(String name); } // 内部类封装单服务的状态 private static class ServiceState<T> { final AtomicInteger refCount = new AtomicInteger(0); T service; } public NamedServiceManager(ServiceFactory<T> serviceFactory) { this.serviceFactory = serviceFactory; } public void start(String name) { // 线程安全地获取或创建服务状态 ServiceState<T> state = serviceStates.computeIfAbsent(name, k -> new ServiceState<>()); int currentCount = state.refCount.incrementAndGet(); if (currentCount == 1) { // 首次启动,创建并启动服务 state.service = serviceFactory.createService(name); startUnderlyingService(state.service); } } public void stop(String name) { ServiceState<T> state = serviceStates.get(name); if (state == null) return; int currentCount = state.refCount.decrementAndGet(); if (currentCount == 0) { // 最后一次停止,关闭服务并移除状态 stopUnderlyingService(state.service); serviceStates.remove(name); } else if (currentCount < 0) { // 处理stop调用次数超过start的异常情况 state.refCount.set(0); throw new IllegalStateException("stop调用次数超过start:" + name); } } // 封装底层服务的启动逻辑,可根据实际服务类型调整 private void startUnderlyingService(T service) { if (service instanceof Startable) { ((Startable) service).start(); } // 也可通过反射或自定义逻辑调用服务启动方法 } // 封装底层服务的停止逻辑 private void stopUnderlyingService(T service) { if (service instanceof Stoppable) { ((Stoppable) service).stop(); } } // 可选:定义服务需实现的标准接口,规范start/stop方法 public interface Startable { void start(); } public interface Stoppable { void stop(); } }
关键细节说明
- 线程安全保障:
ConcurrentHashMap的computeIfAbsent方法保证多线程下不会重复创建服务状态;AtomicInteger确保计数增减操作原子性 - 泛型适配:通过
ServiceFactory接口解耦服务创建逻辑,该管理器可适配任意类型的底层服务 - 异常防护:对
stop调用次数超过start的情况做了容错处理,避免计数器出现负数
使用示例
// 自定义一个底层服务 public class MyService implements NamedServiceManager.Startable, NamedServiceManager.Stoppable { private final String name; public MyService(String name) { this.name = name; } @Override public void start() { System.out.println("启动服务:" + name); // 实际启动逻辑,比如连接资源、初始化线程池等 } @Override public void stop() { System.out.println("停止服务:" + name); // 实际停止逻辑,比如释放资源、关闭线程池等 } } // 多线程场景下使用管理器 public class Main { public static void main(String[] args) { NamedServiceManager<MyService> manager = new NamedServiceManager<>(MyService::new); // 两个线程启动同一个服务 new Thread(() -> manager.start("serviceA")).start(); new Thread(() -> manager.start("serviceA")).start(); // 两个线程停止同一个服务 new Thread(() -> manager.stop("serviceA")).start(); new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } manager.stop("serviceA"); }).start(); } }
Python泛型适配思路(类型提示实现)
如果用Python开发,核心逻辑一致,通过线程锁保证并发安全:
from typing import Generic, TypeVar, Callable, Optional import threading T = TypeVar('T') class ServiceState(Generic[T]): def __init__(self): self.ref_count = 0 self.service: Optional[T] = None self.lock = threading.Lock() class NamedServiceManager(Generic[T]): def __init__(self, service_factory: Callable[[str], T]): self.service_factory = service_factory self._states: dict[str, ServiceState[T]] = {} self._global_lock = threading.Lock() def start(self, name: str): with self._global_lock: state = self._states.get(name) if not state: state = ServiceState[T]() self._states[name] = state with state.lock: state.ref_count += 1 if state.ref_count == 1: state.service = self.service_factory(name) if hasattr(state.service, 'start'): getattr(state.service, 'start')() def stop(self, name: str): with self._global_lock: state = self._states.get(name) if not state: return with state.lock: state.ref_count -= 1 if state.ref_count == 0: if hasattr(state.service, 'stop'): getattr(state.service, 'stop')() with self._global_lock: del self._states[name] elif state.ref_count < 0: state.ref_count = 0 raise ValueError(f"stop调用次数超过start:{name}")
内容的提问来源于stack exchange,提问作者KamilCuk
相关产品推荐
相关产品推荐

