首页 > 解决方案 > 在多线程环境中制作 volatile Executor 类

问题描述

在我基于 Spring 的应用程序中,我们使用 ExecutorService 初始化 threadPool 以执行并发任务。我们不希望在多线程环境中多次初始化 threadPool,为此我们将工厂类设置为 Singleton。下面是我们用于线程池初始化的工厂实现。声纳分析在下面的行中给出了一个错误警告,即“从该字段中删除“volatile”关键字”—— private static volatile ExecutorService executor; 是否需要使我们的ExecutorServiceasVolatile实现上述行为。下面是工厂类

public class ThreadPoolExecutorFactory {

    /** The executor. */
    private static volatile ExecutorService executor;

    /**
     * Instantiates a new thread pool executor factory.
     */
    private ThreadPoolExecutorFactory() {
        // preventing Singleton object instantiation from outside
    }

    /**
     * Gets the executor.
     *
     * @return the executor
     */
    public static ExecutorService getExecutor( ) {
        if(executor == null) {
            synchronized (ThreadPoolExecutorFactory.class) {
                if(executor == null) {
                    executor = Executors.newCachedThreadPool();
                    Runtime.getRuntime().addShutdownHook(new Thread() {
                        @Override
                        public void run() {
                            executor.shutdown();
                        }
                    });
                }
            }
        }
        return executor;
    }
}

标签: javamultithreadingconcurrencysingletonjava-threads

解决方案


我认为您将 Java 独立多线程概念与 Spring 混合在一起。在 Spring 中,您可以将类定义为具有“单例”范围(默认)的“Bean”。你可以有一个保证被调用的 init 方法和一个 destroy 方法。

在 applicationContext.xml 中,定义 bean 如下:

    <bean id="myExecutor" class="my.package.factories.ThreadPoolExecutorFactory"
                        scope="singleton"
                        init-method = "init"
                        destroy-method = "destroy">

并更改类如下:

package my.package.factories

public class ThreadPoolExecutorFactory {

    /** The executor. */
    private static ExecutorService executor;


    public void init() {
        executor = Executors.newCachedThreadPool();
    }

    public void destroy() {
        executor.shutdown();
    }

    /**
     * Gets the executor.
     *
     * @return the executor
     */
    public static ExecutorService getExecutor( ) {
        return executor;
    }
}

Spring 将处理其余的细节。


推荐阅读