You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带构造析构的线程安全计数式单例?多线程场景适配

泛型服务管理器设计方案

核心解决思路

  • 用线程安全的全局映射容器按服务名称共享状态(计数器+服务实例),避免每个对象单独维护计数导致的重复启停
  • 计数器用原子类保证多线程下的增减操作原子性,防止并发计数错误
  • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:32:38