/* * Copyright 2016-2018 Nextop Co.,Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.nextop.lite.pool.util.scheduler.impl.executor; import cn.nextop.lite.pool.util.Concurrents; import cn.nextop.lite.pool.util.concurrent.thread.XThreadFactory; import cn.nextop.lite.pool.util.scheduler.Job; import cn.nextop.lite.pool.util.scheduler.impl.AbstractScheduler; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** * @author Jingqi Xu */ public class ExecutorScheduler extends AbstractScheduler<ExecutorTrigger> { // private final int corePoolSize; private final AtomicReference<ThreadFactory> factory; private final AtomicReference<ScheduledThreadPoolExecutor> executor; /** * */ public ExecutorScheduler(String name, int corePoolSize) { this(name, corePoolSize, new XThreadFactory(name)); } public ExecutorScheduler(String name, int corePoolSize, ThreadFactory tf) { super(name); this.factory = new AtomicReference<ThreadFactory>(tf); this.verbose = false; this.corePoolSize = corePoolSize; this.executor = new AtomicReference<ScheduledThreadPoolExecutor>(); } protected void doStart() throws Exception { // 1 super.doStart(); // 2 this.factory.compareAndSet(null, new XThreadFactory(name, false)); ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(this.corePoolSize); s.setRemoveOnCancelPolicy(true); s.setThreadFactory(factory.get()); executor.set(s); } protected long doStop(long timeout, TimeUnit unit) throws Exception { // 2 timeout = Concurrents.terminate(this.executor.getAndSet(null), timeout, unit); // 1 return super.doStop(timeout, unit); } /** * */ @Override protected void doUnschedule(RunnableJob rj) throws Exception { ((ScheduledFuture<?>)rj.getCookie()).cancel(true); } @Override protected void doSchedule(final RunnableJob rj) throws Exception { Job<ExecutorTrigger> job = rj.getJob(); final ExecutorTrigger t = job.getTrigger(); final long delay = t.getDelay(), interval = t.getInterval(); if(interval <= 0) { rj.setCookie(this.executor.get().schedule(rj, delay, t.getTimeUnit())); } else { final TimeUnit unit = t.getTimeUnit(); if(t.isFixedRate()) { rj.setCookie(executor.get().scheduleAtFixedRate(rj, delay, interval, unit)); } else { rj.setCookie(executor.get().scheduleWithFixedDelay(rj, delay, interval, unit)); } } } }