鍍金池/ 問答/Java/ Executors創(chuàng)建單個(gè)線程池為什么出現(xiàn)兩個(gè)線程池

Executors創(chuàng)建單個(gè)線程池為什么出現(xiàn)兩個(gè)線程池

@Component
public class StatusListener implements ServletContextAware {

final ReentrantLock lock = new ReentrantLock();

@Override
public void setServletContext(ServletContext servletContext) {
    Runnable runnable = new Runnable() {
        public void run() {
            statusTask();
        }
    };

    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

    // 第二個(gè)參數(shù)為首次執(zhí)行的延時(shí)時(shí)間,第三個(gè)參數(shù)為定時(shí)執(zhí)行的間隔時(shí)間
    service.scheduleAtFixedRate(runnable, 20, 60, TimeUnit.SECONDS);
}

public void statusTask() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        System.out.println(Thread.currentThread().getName());
        System.out.println(Thread.currentThread().getId());

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

}

運(yùn)行結(jié)果為:
pool-2-thread-1
40

pool-4-thread-1
42

回答
編輯回答
澐染

spring 初始化的時(shí)候,setServletContext 這個(gè)方法會(huì)調(diào)用二次(或者多次)。自己去看看api,所以你上面的代碼會(huì)初始化了不止一個(gè)的線程連接池。
你可以自己試試,在setServletContext 方法中打印一句話,看看執(zhí)行了幾次。
注意看下面對(duì)應(yīng)api的注釋。

public interface ServletContextAware extends Aware {

    /**
     * Set the {@link ServletContext} that this object runs in.
     * <p>Invoked after population of normal bean properties but before an init
     * callback like InitializingBean's {@code afterPropertiesSet} or a
     * custom init-method. Invoked after ApplicationContextAware's
     * {@code setApplicationContext}.
     * @param servletContext ServletContext object to be used by this object
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     * @see org.springframework.context.ApplicationContextAware#setApplicationContext
     */
    void setServletContext(ServletContext servletContext);

}
2018年4月30日 15:37