ScheduledExecutor服务复用

问题描述 投票:0回答:3

所以,假设我有以下内容

ScheduledExecutorService

public class Foo
{
        private ScheduledExecutorService exec;

        public Foo()
        {
            exec = Executors.newScheduledThreadPool(NUM_OF_TASKS);
        }

        public void executeOnce()
        {
            exec.schedule(new Runnable(){
                @Override
                public void run()
                {
                    Foo.this.doSomething();
                }}, DELAY, TimeUnit.MILLISECONDS);
        }
}

现在,

exec
用于执行周期性任务(例如目录轮询等)。但是,有一个任务(即
executeOnce
)会执行 一次,但需要延迟。所以,我选择使用
exec
来执行这个任务,但是这样的设计好吗?相反,我应该创建一个
newSingleThreadExecutor
,然后调用
shutdown
吗?例如,

public void executeOnce()
{
    // Execute task and wait 'til completion      
    ExecutorService exec = Executors.newSingleThreadExecutor();
    try {
        exec.submit(new Runnable(){
            @Override
            public void run() 
            {   
                try 
                {
                    Thread.sleep(DELAY);
                } catch (InterruptedException e) {
                }
                Foo.this.doSomething()
            }   
        }).get();
    } catch (InterruptedException e) {
    } catch (ExecutionException e) {
    }

    // Shutdown executor service    
    exec.shutdownNow();        
 }

实施后者有什么好处吗?

java executorservice
3个回答
1
投票
如果常规任务和一次性任务以某种方式相关

并且常规任务的调度并不那么重要,以至于它们的执行(可能的)延迟是一个问题,那么我只需执行一个-同一执行器上的时间任务。

使用单独的执行器的优点是可以不受干扰地安排常规任务。然而

shutdownNow()

在这里
几乎肯定不会达到预期的效果,简单的shutdown()
会更合适。


1
投票
如果 exec 被重用于其他任务,那么最初的部分让我觉得更优雅。创建线程是一项不平凡的任务,即使可运行对象只被执行一次,线程化的一般方法是创建一个线程池并向它们抛出可运行对象。让生活更轻松,集中线程池等等......


0
投票
必须为 GC 创建和销毁线程对象。仅将一个线程重复用于多个任务可能会在系统中产生问题。

© www.soinside.com 2019 - 2024. All rights reserved.