在本文中,我们将给您介绍关于如何有效地取消定期的ScheduledExecutorService任务的详细内容,并且为您解答取消定期怎么取消的相关问题,此外,我们还将为您提供关于Executors的3
在本文中,我们将给您介绍关于如何有效地取消定期的ScheduledExecutorService任务的详细内容,并且为您解答取消定期怎么取消的相关问题,此外,我们还将为您提供关于Executors 的 3 种常用线程池及 ScheduledExecutorService、Executors框架之ScheduledExecutorService实现定时任务、Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolEx...、java – 使用ScheduledExecutorService的多个任务的知识。
本文目录一览:- 如何有效地取消定期的ScheduledExecutorService任务(取消定期怎么取消)
- Executors 的 3 种常用线程池及 ScheduledExecutorService
- Executors框架之ScheduledExecutorService实现定时任务
- Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolEx...
- java – 使用ScheduledExecutorService的多个任务
如何有效地取消定期的ScheduledExecutorService任务(取消定期怎么取消)
因此,使用此链接作为参考,任何人都可以提出更优雅的解决方案来取消定期的ScheduledExecutorService任务吗?
这是我目前正在做的事的一个例子:
// do stuff// Schedule periodic taskcurrentTask = exec.scheduleAtFixedRate( new RequestProgressRunnable(), 0, 5000, TimeUnit.MILLISECONDS);// Runnableprivate class RequestProgressRunnable implements Runnable{ // Field members private Integer progressValue = 0; @Override public void run() { // do stuff // Check progress value if (progressValue == 100) { // Cancel task getFuture().cancel(true); } else { // Increment progress value progressValue += 10; } } } /** * Gets the future object of the scheduled task * @return Future object */ public Future<?> getFuture() { return currentTask; }
答案1
小编典典我建议您使用int并自己安排任务。
executor.schedule(new RequestProgressRunnable(), 5000, TimeUnit.MILLISECONDS);class RequestProgressRunnable implements Runnable { private int count = 0; public void run() { // do stuff // Increment progress value progressValue += 10; // Check progress value if (progressValue < 100) executor.schedule(this, 5000, TimeUnit.MILLISECONDS); }}
Executors 的 3 种常用线程池及 ScheduledExecutorService
一.3 种常用的线程池
public class Executors {
/**
* Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue. At any point, at most
* {@code nThreads} threads will be active processing tasks.
* If additional tasks are submitted when all threads are active,
* they will wait in the queue until a thread is available.
* If any thread terminates due to a failure during execution
* prior to shutdown, a new one will take its place if needed to
* execute subsequent tasks. The threads in the pool will exist
* until it is explicitly {@link ExecutorService#shutdown shutdown}.
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
/**
* Creates a thread pool that maintains enough threads to support
* the given parallelism level, and may use multiple queues to
* reduce contention. The parallelism level corresponds to the
* maximum number of threads actively engaged in, or available to
* engage in, task processing. The actual number of threads may
* grow and shrink dynamically. A work-stealing pool makes no
* guarantees about the order in which submitted tasks are
* executed.
*
* @param parallelism the targeted parallelism level
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code parallelism <= 0}
* @since 1.8
*/
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
/**
* Creates a work-stealing thread pool using all
* {@link Runtime#availableProcessors available processors}
* as its target parallelism level.
* @return the newly created thread pool
* @see #newWorkStealingPool(int)
* @since 1.8
*/
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
/**
* Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue, using the provided
* ThreadFactory to create new threads when needed. At any point,
* at most {@code nThreads} threads will be active processing
* tasks. If additional tasks are submitted when all threads are
* active, they will wait in the queue until a thread is
* available. If any thread terminates due to a failure during
* execution prior to shutdown, a new one will take its place if
* needed to execute subsequent tasks. The threads in the pool will
* exist until it is explicitly {@link ExecutorService#shutdown
* shutdown}.
*
* @param nThreads the number of threads in the pool
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
* @throws NullPointerException if threadFactory is null
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
/**
* Creates an Executor that uses a single worker thread operating
* off an unbounded queue. (Note however that if this single
* thread terminates due to a failure during execution prior to
* shutdown, a new one will take its place if needed to execute
* subsequent tasks.) Tasks are guaranteed to execute
* sequentially, and no more than one task will be active at any
* given time. Unlike the otherwise equivalent
* {@code newFixedThreadPool(1)} the returned executor is
* guaranteed not to be reconfigurable to use additional threads.
*
* @return the newly created single-threaded Executor
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
/**
* Creates an Executor that uses a single worker thread operating
* off an unbounded queue, and uses the provided ThreadFactory to
* create a new thread when needed. Unlike the otherwise
* equivalent {@code newFixedThreadPool(1, threadFactory)} the
* returned executor is guaranteed not to be reconfigurable to use
* additional threads.
*
* @param threadFactory the factory to use when creating new
* threads
*
* @return the newly created single-threaded Executor
* @throws NullPointerException if threadFactory is null
*/
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
/**
* Creates a thread pool that creates new threads as needed, but
* will reuse previously constructed threads when they are
* available. These pools will typically improve the performance
* of programs that execute many short-lived asynchronous tasks.
* Calls to {@code execute} will reuse previously constructed
* threads if available. If no existing thread is available, a new
* thread will be created and added to the pool. Threads that have
* not been used for sixty seconds are terminated and removed from
* the cache. Thus, a pool that remains idle for long enough will
* not consume any resources. Note that pools with similar
* properties but different details (for example, timeout parameters)
* may be created using {@link ThreadPoolExecutor} constructors.
*
* @return the newly created thread pool
*/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
/**
* Creates a thread pool that creates new threads as needed, but
* will reuse previously constructed threads when they are
* available, and uses the provided
* ThreadFactory to create new threads when needed.
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
* @throws NullPointerException if threadFactory is null
*/
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
/**
* Creates a single-threaded executor that can schedule commands
* to run after a given delay, or to execute periodically.
* (Note however that if this single
* thread terminates due to a failure during execution prior to
* shutdown, a new one will take its place if needed to execute
* subsequent tasks.) Tasks are guaranteed to execute
* sequentially, and no more than one task will be active at any
* given time. Unlike the otherwise equivalent
* {@code newScheduledThreadPool(1)} the returned executor is
* guaranteed not to be reconfigurable to use additional threads.
* @return the newly created scheduled executor
*/
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
/**
* Creates a single-threaded executor that can schedule commands
* to run after a given delay, or to execute periodically. (Note
* however that if this single thread terminates due to a failure
* during execution prior to shutdown, a new one will take its
* place if needed to execute subsequent tasks.) Tasks are
* guaranteed to execute sequentially, and no more than one task
* will be active at any given time. Unlike the otherwise
* equivalent {@code newScheduledThreadPool(1, threadFactory)}
* the returned executor is guaranteed not to be reconfigurable to
* use additional threads.
* @param threadFactory the factory to use when creating new
* threads
* @return a newly created scheduled executor
* @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
/**
* Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
* @return a newly created scheduled thread pool
* @throws IllegalArgumentException if {@code corePoolSize < 0}
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
/**
* Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
* @param threadFactory the factory to use when the executor
* creates a new thread
* @return a newly created scheduled thread pool
* @throws IllegalArgumentException if {@code corePoolSize < 0}
* @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
/**
* Returns an object that delegates all defined {@link
* ExecutorService} methods to the given executor, but not any
* other methods that might otherwise be accessible using
* casts. This provides a way to safely "freeze" configuration and
* disallow tuning of a given concrete implementation.
* @param executor the underlying implementation
* @return an {@code ExecutorService} instance
* @throws NullPointerException if executor null
*/
public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
if (executor == null)
throw new NullPointerException();
return new DelegatedExecutorService(executor);
}
/**
* Returns an object that delegates all defined {@link
* ScheduledExecutorService} methods to the given executor, but
* not any other methods that might otherwise be accessible using
* casts. This provides a way to safely "freeze" configuration and
* disallow tuning of a given concrete implementation.
* @param executor the underlying implementation
* @return a {@code ScheduledExecutorService} instance
* @throws NullPointerException if executor null
*/
public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
if (executor == null)
throw new NullPointerException();
return new DelegatedScheduledExecutorService(executor);
}
/**
* Returns a default thread factory used to create new threads.
* This factory creates all new threads used by an Executor in the
* same {@link ThreadGroup}. If there is a {@link
* java.lang.SecurityManager}, it uses the group of {@link
* System#getSecurityManager}, else the group of the thread
* invoking this {@code defaultThreadFactory} method. Each new
* thread is created as a non-daemon thread with priority set to
* the smaller of {@code Thread.NORM_PRIORITY} and the maximum
* priority permitted in the thread group. New threads have names
* accessible via {@link Thread#getName} of
* <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
* number of this factory, and <em>M</em> is the sequence number
* of the thread created by this factory.
* @return a thread factory
*/
public static ThreadFactory defaultThreadFactory() {
return new DefaultThreadFactory();
}
/**
* Returns a thread factory used to create new threads that
* have the same permissions as the current thread.
* This factory creates threads with the same settings as {@link
* Executors#defaultThreadFactory}, additionally setting the
* AccessControlContext and contextClassLoader of new threads to
* be the same as the thread invoking this
* {@code privilegedThreadFactory} method. A new
* {@code privilegedThreadFactory} can be created within an
* {@link AccessController#doPrivileged AccessController.doPrivileged}
* action setting the current thread''s access control context to
* create threads with the selected permission settings holding
* within that action.
*
* <p>Note that while tasks running within such threads will have
* the same access control and class loader settings as the
* current thread, they need not have the same {@link
* java.lang.ThreadLocal} or {@link
* java.lang.InheritableThreadLocal} values. If necessary,
* particular values of thread locals can be set or reset before
* any task runs in {@link ThreadPoolExecutor} subclasses using
* {@link ThreadPoolExecutor#beforeExecute(Thread, Runnable)}.
* Also, if it is necessary to initialize worker threads to have
* the same InheritableThreadLocal settings as some other
* designated thread, you can create a custom ThreadFactory in
* which that thread waits for and services requests to create
* others that will inherit its values.
*
* @return a thread factory
* @throws AccessControlException if the current access control
* context does not have permission to both get and set context
* class loader
*/
public static ThreadFactory privilegedThreadFactory() {
return new PrivilegedThreadFactory();
}
/**
* Returns a {@link Callable} object that, when
* called, runs the given task and returns the given result. This
* can be useful when applying methods requiring a
* {@code Callable} to an otherwise resultless action.
* @param task the task to run
* @param result the result to return
* @param <T> the type of the result
* @return a callable object
* @throws NullPointerException if task null
*/
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
/**
* Returns a {@link Callable} object that, when
* called, runs the given task and returns {@code null}.
* @param task the task to run
* @return a callable object
* @throws NullPointerException if task null
*/
public static Callable<Object> callable(Runnable task) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<Object>(task, null);
}
/**
* Returns a {@link Callable} object that, when
* called, runs the given privileged action and returns its result.
* @param action the privileged action to run
* @return a callable object
* @throws NullPointerException if action null
*/
public static Callable<Object> callable(final PrivilegedAction<?> action) {
if (action == null)
throw new NullPointerException();
return new Callable<Object>() {
public Object call() { return action.run(); }};
}
/**
* Returns a {@link Callable} object that, when
* called, runs the given privileged exception action and returns
* its result.
* @param action the privileged exception action to run
* @return a callable object
* @throws NullPointerException if action null
*/
public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
if (action == null)
throw new NullPointerException();
return new Callable<Object>() {
public Object call() throws Exception { return action.run(); }};
}
/**
* Returns a {@link Callable} object that will, when called,
* execute the given {@code callable} under the current access
* control context. This method should normally be invoked within
* an {@link AccessController#doPrivileged AccessController.doPrivileged}
* action to create callables that will, if possible, execute
* under the selected permission settings holding within that
* action; or if not possible, throw an associated {@link
* AccessControlException}.
* @param callable the underlying task
* @param <T> the type of the callable''s result
* @return a callable object
* @throws NullPointerException if callable null
*/
public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
if (callable == null)
throw new NullPointerException();
return new PrivilegedCallable<T>(callable);
}
/**
* Returns a {@link Callable} object that will, when called,
* execute the given {@code callable} under the current access
* control context, with the current context class loader as the
* context class loader. This method should normally be invoked
* within an
* {@link AccessController#doPrivileged AccessController.doPrivileged}
* action to create callables that will, if possible, execute
* under the selected permission settings holding within that
* action; or if not possible, throw an associated {@link
* AccessControlException}.
*
* @param callable the underlying task
* @param <T> the type of the callable''s result
* @return a callable object
* @throws NullPointerException if callable null
* @throws AccessControlException if the current access control
* context does not have permission to both set and get context
* class loader
*/
public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
if (callable == null)
throw new NullPointerException();
return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
}
// Non-public classes supporting the public methods
/**
* A callable that runs given task and returns given result
*/
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
/**
* A callable that runs under established access control settings
*/
static final class PrivilegedCallable<T> implements Callable<T> {
private final Callable<T> task;
private final AccessControlContext acc;
PrivilegedCallable(Callable<T> task) {
this.task = task;
this.acc = AccessController.getContext();
}
public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
return task.call();
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}
/**
* A callable that runs under established access control settings and
* current ClassLoader
*/
static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
private final Callable<T> task;
private final AccessControlContext acc;
private final ClassLoader ccl;
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Calls to getContextClassLoader from this class
// never trigger a security check, but we check
// whether our callers have this permission anyways.
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
// Whether setContextClassLoader turns out to be necessary
// or not, we fail fast if permission is not available.
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.task = task;
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}
public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
Thread t = Thread.currentThread();
ClassLoader cl = t.getContextClassLoader();
if (ccl == cl) {
return task.call();
} else {
t.setContextClassLoader(ccl);
try {
return task.call();
} finally {
t.setContextClassLoader(cl);
}
}
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}
/**
* The default thread factory
*/
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
/**
* Thread factory capturing access control context and class loader
*/
static class PrivilegedThreadFactory extends DefaultThreadFactory {
private final AccessControlContext acc;
private final ClassLoader ccl;
PrivilegedThreadFactory() {
super();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Calls to getContextClassLoader from this class
// never trigger a security check, but we check
// whether our callers have this permission anyways.
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
// Fail fast
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}
public Thread newThread(final Runnable r) {
return super.newThread(new Runnable() {
public void run() {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
Thread.currentThread().setContextClassLoader(ccl);
r.run();
return null;
}
}, acc);
}
});
}
}
/**
* A wrapper class that exposes only the ExecutorService methods
* of an ExecutorService implementation.
*/
static class DelegatedExecutorService extends AbstractExecutorService {
private final ExecutorService e;
DelegatedExecutorService(ExecutorService executor) { e = executor; }
public void execute(Runnable command) { e.execute(command); }
public void shutdown() { e.shutdown(); }
public List<Runnable> shutdownNow() { return e.shutdownNow(); }
public boolean isShutdown() { return e.isShutdown(); }
public boolean isTerminated() { return e.isTerminated(); }
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
return e.awaitTermination(timeout, unit);
}
public Future<?> submit(Runnable task) {
return e.submit(task);
}
public <T> Future<T> submit(Callable<T> task) {
return e.submit(task);
}
public <T> Future<T> submit(Runnable task, T result) {
return e.submit(task, result);
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
return e.invokeAll(tasks);
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
return e.invokeAll(tasks, timeout, unit);
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
return e.invokeAny(tasks);
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return e.invokeAny(tasks, timeout, unit);
}
}
static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
protected void finalize() {
super.shutdown();
}
}
/**
* A wrapper class that exposes only the ScheduledExecutorService
* methods of a ScheduledExecutorService implementation.
*/
static class DelegatedScheduledExecutorService
extends DelegatedExecutorService
implements ScheduledExecutorService {
private final ScheduledExecutorService e;
DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
super(executor);
e = executor;
}
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
return e.schedule(command, delay, unit);
}
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
return e.schedule(callable, delay, unit);
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
return e.scheduleAtFixedRate(command, initialDelay, period, unit);
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
}
}
/** Cannot instantiate. */
private Executors() {}
}
Executors 这个工具类中提供了如下静态方法:
- Executors.newCachedThreadPool () 无限大小的线程池,线程会自动重用
- Executors.newFixedThreadPool (int) 固定线程数的线程池
- Executors.newSingleThreadExecutor () 单线程执行器
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);
- corePoolSize 是线程池的核心线程数,通常线程池会维持这个线程数
- maximumPoolSize 是线程池所能维持的最大线程数
- keepAliveTime 和 unit 则分别是超额线程的空闲存活时间数和时间单位
- workQueue 是提交任务到线程池的入队列
- threadFactory 是线程池创建新线程的线程构造器
- handler 是当线程池不能接受提交任务的时候的处理策略
1. 参数:int corePoolSize
- 如果当前线程池中线程的数目低于 corePoolSize,则创建新线程执行提交的任务,而无需检查当前是否有空闲线程
- 如果提交任务时线程池中线程数已达到 corePoolSize,则将提交的任务加入等待执行队列
- 如果提交任务时等待执行的任务队列是有限队列,而且已满,则在线程池中开辟新线程执行此任务
- 如果线程池中线程数目已达到 maximumPoolSize,则提交的任务交由 RejectedExecutionHandler 处理
3. 参数:RejectedExecutionHandler handler
对于任务丢弃,ThreadPoolExecutor 以内部类的形式实现了 4 个策略。分别是:
- CallerRunsPolicy。提交任务的线程自己负责执行这个任务。
- AbortPolicy。使 Executor 抛出异常,通过异常做处理。
- DiscardPolicy。丢弃提交的任务。
- DiscardOldestPolicy。丢弃掉队列中最早加入的任务。
在调用构造方法时,参数中未指定 RejectedExecutionHandler 情况下,默认采用 AbortPolicy。
Utils:
package com.river.util;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class CommonThreadPool {
/** 获取可用CPU数目 */
private static int PROCESSOR_SIZE = Runtime.getRuntime().availableProcessors();
private static final int CAPACITY = 500;
private static final String PREFIX = "public-pool-thread-";
public static ThreadPoolExecutor POOL(){
return new ThreadPoolExecutor(
/**
* 线程池大小:
* 1.对于CUP密集型,一般设置N+1最优
* 2.对于IO密集型,一般设置2N+1最优
**/
PROCESSOR_SIZE + 1,
PROCESSOR_SIZE + 1,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(CAPACITY),
new ThreadFactory() {
private final AtomicInteger counter = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(Boolean.TRUE);
thread.setName(String.format("%s%d", PREFIX, counter.getAndIncrement()));
return thread;
}
},
new ThreadPoolExecutor.CallerRunsPolicy()
);
}
}
ExecutorService.submit (),execute () 区别
submit () 可以拿到线程执行结果,而 execute () 则不能;
二。线程池 ScheduledExecutorService
该线程池我是在查看Eureka源码是发现的,之前也没怎么接触过;
1.创建方法
/**
* Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
* @return a newly created scheduled thread pool
* @throws IllegalArgumentException if {@code corePoolSize < 0}
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
/**
* Creates a thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
* @param threadFactory the factory to use when the executor
* creates a new thread
* @return a newly created scheduled thread pool
* @throws IllegalArgumentException if {@code corePoolSize < 0}
* @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
2. 我们看一下 ScheduledExecutorService 提供的方法
2.1 这个方法创建了执行一次的延迟任务;
/**
* Creates and executes a one-shot action that becomes enabled
* after the given delay.
*
* @param command the task to execute
* @param delay the time from now to delay execution
* @param unit the time unit of the delay parameter
* @return a ScheduledFuture representing pending completion of
* the task and whose {@code get()} method will return
* {@code null} upon completion
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if command is null
*/
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
2.2 创建了一个延迟执行的循环执行的定时任务,第一次执行时间会在给定的 initialDelay 延迟时间后执行,第二次任务执行开始时间点为 initialDelay+period, 即之后的任务开始执行时间间隔为 period, 注意这里关注的是任务开始执行的时间点;
/**
* Creates and executes a periodic action that becomes enabled first
* after the given initial delay, and subsequently with the given
* period; that is executions will commence after
* {@code initialDelay} then {@code initialDelay+period}, then
* {@code initialDelay + 2 * period}, and so on.
* If any execution of the task
* encounters an exception, subsequent executions are suppressed.
* Otherwise, the task will only terminate via cancellation or
* termination of the executor. If any execution of this task
* takes longer than its period, then subsequent executions
* may start late, but will not concurrently execute.
*
* @param command the task to execute
* @param initialDelay the time to delay first execution
* @param period the period between successive executions
* @param unit the time unit of the initialDelay and period parameters
* @return a ScheduledFuture representing pending completion of
* the task, and whose {@code get()} method will throw an
* exception upon cancellation
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if command is null
* @throws IllegalArgumentException if period less than or equal to zero
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
2.3 执行方式与 2.2 类似,与之不同的是,这里要把上一次任务执行时间算在内;
即第一次任务在给定的延迟时间后执行,第二次任务执行在第一次任务执行完毕后,在给定的延迟时间后执行;
/**
* Creates and executes a periodic action that becomes enabled first
* after the given initial delay, and subsequently with the
* given delay between the termination of one execution and the
* commencement of the next. If any execution of the task
* encounters an exception, subsequent executions are suppressed.
* Otherwise, the task will only terminate via cancellation or
* termination of the executor.
*
* @param command the task to execute
* @param initialDelay the time to delay first execution
* @param delay the delay between the termination of one
* execution and the commencement of the next
* @param unit the time unit of the initialDelay and delay parameters
* @return a ScheduledFuture representing pending completion of
* the task, and whose {@code get()} method will throw an
* exception upon cancellation
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if command is null
* @throws IllegalArgumentException if delay less than or equal to zero
*/
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
https://my.oschina.net/alexgaoyh/blog/410709
Executors框架之ScheduledExecutorService实现定时任务
一、简介
An ExecutorService that can schedule commands to run after a given delay, or to execute periodically. (ExecutorService可以安排命令在给定的延迟后运行或定期执行。)
The schedule methods create tasks with various delays and return a task object that can be used to cancel or check execution. The scheduleAtFixedRate and scheduleWithFixedDelay methods create and execute tasks that run periodically until cancelled. (调度方法会创建具有各种延迟的任务,并返回可用于取消或检查执行的任务对象。 scheduleAtFixedRate和scheduleWithFixedDelay方法创建并执行定期运行的任务,直到被取消为止。 )
Commands submitted using the Executor.execute(java.lang.Runnable) and ExecutorService submit methods are scheduled with a requested delay of zero. Zero and negative delays (but not periods) are also allowed in schedule methods, and are treated as requests for immediate execution. (使用Executor.execute(java.lang.Runnable)和ExecutorService提交方法提交的命令的计划延迟为零。调度方法中还允许零延迟和负延迟(但不允许使用周期),并将其视为立即执行的请求。 )
All schedule methods accept relative delays and periods as arguments, not absolute times or dates. It is a simple matter to transform an absolute time represented as a Date to the required form. For example, to schedule at a certain future date, you can use: schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS). Beware however that expiration of a relative delay need not coincide with the current Date at which the task is enabled due to network time synchronization protocols, clock drift, or other factors. The Executors class provides convenient factory methods for the ScheduledExecutorService implementations provided in this package. (所有调度方法都接受相对延迟和周期作为参数,而不是绝对时间或日期作为参数。将代表日期的绝对时间转换为所需的形式很简单。例如,要计划在某个将来的日期进行计划,可以使用:schedule(task,date.getTime()-System.currentTimeMillis(),TimeUnit.MILLISECONDS)。但是请注意,由于网络时间同步协议,时钟漂移或其他因素,相对延迟的到期时间不必与启用任务的当前日期一致。 Executors类为此程序包中提供的ScheduledExecutorService实现提供了方便的工厂方法。 )
(jdk7 doc , translate by google )
二、两个常用定时任务
1. 固定周期的定时任务
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
创建并执行一个周期性操作,该操作将在给定的初始延迟后首先启用,然后在给定的时间段内启用;即后执行将开始 在initialDelay然后在initialDelay +周期,然后 在initialDelay + 2 *周期,依此类推。
2. 固定延迟的定时任务
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
创建并执行一个周期性操作,该操作将在给定的初始延迟后首先启用,然后在一个执行的终止与下一个执行的开始之间具有给定的延迟。
3. 一次性延迟任务 Runnable
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
创建并执行一次操作,该操作在给定的延迟后变为启用状态。
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
System.out.println("一次性的延迟任务, 10S 后执行");
executorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println("一次性延迟任务");
}
}, 10L, SECONDS);
4. 一次性延迟任务 Callable
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
创建并执行ScheduledFuture,该ScheduledFuture在给定的延迟后变为启用状态。
三、示例代码
class PrintControl {
private final SimpleDateFormat SDF = new SimpleDateFormat("hh:mm:ss");
/**
* @param int corePoolSize 线程池中最小的线程数, 无任务时保持, 任务过多时可以超出这个值
*/
private final ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
/**
* 给定延迟的打印任务
* 以固定的延迟时间(delay)去执行任务
*/
public void printForDelay() {
Runnable print = () -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ScheduledWithFixedDelay" + SDF.format(new Date()));
};
/**
* @param Runnable command
* @param long initialDelay
* @param long delay
* @param TimeUnit unit
*/
scheduled.scheduleWithFixedDelay(print, 0L, 5L, SECONDS);
}
/**
* 定期去执行打印任务
* 以固定的周期(period)去执行任务
*/
public void printForRate() {
Runnable print = () -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ScheduledAtFixedRate" + SDF.format(new Date()));
};
/**
* @param Runnable command
* @param long initialDelay
* @param long period
* @param TimeUnit unit
*/
scheduled.scheduleAtFixedRate(print, 0L, 5L, SECONDS);
}
}
四、通过ThreadFactory 指定任务线程名称
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)
使用ThreadFactory设置明确的线程名称, 这样在调试的时候就可以很清晰的找到任务线程, 便于调试
参考 Executors.defaultThreadFactory()
class PrintControl {
private final ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1, ExecutorsefaultThreadFactory());
}
class PrintThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "PrintThreadFactory");
}
}
五、结束任务
1. 异常抛出
如果任务抛出异常会导致周期任务无法继续进行, 所以最好结合try cache处理.
此时线程不会结束.
final AtomicInteger count = new AtomicInteger(0);
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1, new PrintThreadFactory());
StringBuilder nullPoint = null;
Runnable print = new Runnable() {
@Override
public void run() {
System.out.println("print " + count.getAndIncrement());
// print 4 之后, 任务不再继续执行
if (count.get() == 5) {
nullPoint.toString();
}
}
};
schedule.scheduleAtFixedRate(print, 0L, 2L, SECONDS);
2. 结束任务
Future.cancle(boolean mayInterruptIfRunning)
通过Debugger可以看出, 只是任务结束了,线程还在继续wait
// 最终打印 "print 3"之后打印"is canclelled", 任务不再继续, 线程不被关闭
final AtomicInteger count = new AtomicInteger(0);
final CountDownLatch countDownLatch = new CountDownLatch(1);
Future future = null;
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1, new PrintThreadFactory());
Runnable print = new Runnable() {
@Override
public void run() {
System.out.println("print " + count.getAndIncrement());
if (count.get() == 3) {
countDownLatch.countDown();
}
}
};
future = schedule.scheduleAtFixedRate(print, 0L, 2L, SECONDS);
try {
countDownLatch.await();
future.cancel(true);
if (future.isCancelled()) {
System.out.println("is canclelled");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
3. 结束线程
3.1. void ExecutorService.shutdown();
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. (启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务。)
final AtomicInteger count = new AtomicInteger(0);
final CountDownLatch countDownLatch = new CountDownLatch(1);
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1, new PrintThreadFactory());
Runnable print = new Runnable() {
@Override
public void run() {
System.out.println("print " + count.getAndIncrement());
if (count.get() == 3) {
countDownLatch.countDown();
System.out.println("任务还在继续...");
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务结束");
}
}
};
schedule.scheduleAtFixedRate(print, 0L, 2L, SECONDS);
try {
countDownLatch.await();
schedule.shutdown();
// schedule.shutdownNow();
if (schedule.isShutdown()) {
System.out.println("Schedule is shutdown");
}
// 阻塞
if (schedule.awaitTermination(10L, SECONDS)) {
System.out.println("termination");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
打印结果:
print 0
print 1
print 2
任务还在继续...
Schedule is shutdown
任务结束
termination
3.2. List<Runnable> ExecutorService.shutdownNow();
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. (尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表。)
final AtomicInteger count = new AtomicInteger(0);
final CountDownLatch countDownLatch = new CountDownLatch(1);
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1, new PrintThreadFactory());
Runnable print = new Runnable() {
@Override
public void run() {
System.out.println("print " + count.getAndIncrement());
if (count.get() == 3) {
countDownLatch.countDown();
System.out.println("任务还在继续...");
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务结束");
}
}
};
schedule.scheduleAtFixedRate(print, 0L, 2L, SECONDS);
try {
countDownLatch.await();
// schedule.shutdown();
schedule.shutdownNow();
if (schedule.isShutdown()) {
System.out.println("Schedule is shutdown");
}
// 阻塞
if (schedule.awaitTermination(10L, SECONDS)) {
System.out.println("termination");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
打印结果: 可以看出 Thread.sleep()
发生了中断异常
print 0
print 1
print 2
任务还在继续...
Schedule is shutdown
java.lang.InterruptedException: sleep interrupted
...
任务结束
termination
3.3. boolean ExecutorService.awaitTermination(long timeout, TimeUnit unit)
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first. (阻塞直到关闭请求后所有任务完成执行,或者发生超时,或者当前线程被中断(以先发生的为准)。)
六、参考
- Interface ScheduledExecutorService (jdk8 doc)
- Interface ExecutorService (jdk8 doc)
Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolEx...
<divitemprop="text"><!-- Quick Adsense WordPress Plugin: http://quickadsense.com/ --> <div> <div data-type="ad" data-publisher="journaldev.com" data-zone="jd_after_entry_728x90" data-format="728x90"> </div> </div> <p>Welcome to the Java Scheduler Example. Today we will look into <code>ScheduledExecutorService</code> and it’s implementation class <code>ScheduledThreadPoolExecutor</code> example.</p> <div id="toc_container"><p>Table of Contents <span>[<a href="#">hide</a>]</span></p><ul><li><a href="#java-scheduler-scheduledexecutorservice"><span>1</span> Java Scheduler ScheduledExecutorService</a><ul><li><a href="#java-scheduler-example"><span>1.1</span> Java Scheduler Example</a></li><li><a href="#scheduledexecutorservice-scheduleatfixedraterunnable-commandlong-initialdelaylong-periodtimeunit-unit"><span>1.2</span> ScheduledExecutorService scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)</a></li><li><a href="#scheduledexecutorservice-schedulewithfixeddelayrunnable-commandlong-initialdelaylong-delaytimeunit-unit"><span>1.3</span> ScheduledExecutorService scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit)</a></li></ul></li></ul></div> <h2><span id="java-scheduler-scheduledexecutorservice">Java Scheduler ScheduledExecutorService</span></h2> <p><a href="//cdn.journaldev.com/wp-content/uploads/2013/10/java-scheduler-example-scheduledexecutorservice-scheduledthreadpoolexecutor.jpg"><img src="//cdn.journaldev.com/wp-content/uploads/2013/10/java-scheduler-example-scheduledexecutorservice-scheduledthreadpoolexecutor.jpg" alt="java scheduler, java scheduler example, ScheduledExecutorService, ScheduledThreadPoolExecutor" width="560" height="315"srcset="//cdn.journaldev.com/wp-content/uploads/2013/10/java-scheduler-example-scheduledexecutorservice-scheduledthreadpoolexecutor.jpg 560w, //cdn.journaldev.com/wp-content/uploads/2013/10/java-scheduler-example-scheduledexecutorservice-scheduledthreadpoolexecutor-450x253.jpg 450w, //cdn.journaldev.com/wp-content/uploads/2013/10/java-scheduler-example-scheduledexecutorservice-scheduledthreadpoolexecutor-20x11.jpg 20w" sizes="(max-width: 560px) 100vw, 560px"></a><br> Sometimes we need to execute a task periodically or after specific delay. Java provides <a href="https://www.journaldev.com/1050/java-timer-timertask-example"><strong>Timer Class</strong></a> through which we can achieve this but sometimes we need to run similar tasks in parallel. So creating multiple Timer objects will be an overhead to the system and it’s better to have a thread pool of scheduled tasks. </p> <p>Java provides scheduled thread pool implementation through <code>ScheduledThreadPoolExecutor</code> class that implements <code>ScheduledExecutorService</code> interface. ScheduledExecutorService defines the contract methods to schedule a task with different options.</p> <p>Sometime back I wrote a post about <a href="https://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice">Java ThreadPoolExecutor</a> where I was using Executors class to create the thread pool. Executors class also provide factory methods to create <strong>ScheduledThreadPoolExecutor</strong> where we can specify the number of threads in the pool.</p> <h3><span id="java-scheduler-example">Java Scheduler Example</span></h3> <p>Let’s say we have a simple Runnable class like below.</p> <p><code>WorkerThread.java</code></p> <!-- Quick Adsense WordPress Plugin: http://quickadsense.com/ --> <div> <div data-type="ad" data-publisher="journaldev.com" data-format="300x250" data-zone="jd_post_mid_300x250"></div> </div>
<pre><code><div>Copy</div> <span>package</span> com.journaldev.threads; <span>import</span> java.util.Date; <span>public</span> <span><span>class</span> <span>WorkerThread</span> <span>implements</span> <span>Runnable</span></span>{ <span>private</span> String command; <span><span>public</span> <span>WorkerThread</span><span>(String s)</span></span>{ <span>this</span>.command=s; } <span>@Override</span> <span><span>public</span> <span>void</span> <span>run</span><span>()</span> </span>{ System.out.println(Thread.currentThread().getName()+<span>" Start. Time = "</span>+<span>new</span> Date()); processCommand(); System.out.println(Thread.currentThread().getName()+<span>" End. Time = "</span>+<span>new</span> Date()); } <span><span>private</span> <span>void</span> <span>processCommand</span><span>()</span> </span>{ <span>try</span> { Thread.sleep(<span>5000</span>); } <span>catch</span> (InterruptedException e) { e.printStackTrace(); } } <span>@Override</span> <span><span>public</span> String <span>toString</span><span>()</span></span>{ <span>return</span> <span>this</span>.command; } } </code></pre>
<p>It’s a simple Runnable class that takes around 5 seconds to execute its task.</p> <p>Let’s see a simple example where we will schedule the worker thread to execute after 10 seconds delay. We will use Executors class <code>newScheduledThreadPool(int corePoolSize)</code> method that returns instance of <code>ScheduledThreadPoolExecutor</code>. Here is the code snippet from Executors class.</p> <pre><code><div>Copy</div><span> <span>public</span> <span>static</span> ScheduledExecutorService <span>newScheduledThreadPool</span><span>(<span>int</span> corePoolSize)</span> </span>{ <span>return</span> <span>new</span> ScheduledThreadPoolExecutor(corePoolSize); } </code></pre> <p>Below is our java scheduler example program using <code>ScheduledExecutorService</code> and <code>ScheduledThreadPoolExecutor</code> implementation.</p> <pre><code><div>Copy</div> <span>package</span> com.journaldev.threads;
<span>import</span> java.util.Date; <span>import</span> java.util.concurrent.Executors; <span>import</span> java.util.concurrent.ScheduledExecutorService; <span>import</span> java.util.concurrent.TimeUnit;
<span>public</span> <span><span>class</span> <span>ScheduledThreadPool</span> </span>{
<span><span>public</span> <span>static</span> <span>void</span> <span>main</span><span>(String[] args)</span> <span>throws</span> InterruptedException </span>{
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(<span>5</span>);
<span>//schedule to run after sometime</span>
System.out.println(<span>"Current Time = "</span>+<span>new</span> Date());
<span>for</span>(<span>int</span> i=<span>0</span>; i<<span>3</span>; i++){
Thread.sleep(<span>1000</span>);
WorkerThread worker = <span>new</span> WorkerThread(<span>"do heavy processing"</span>);
scheduledThreadPool.schedule(worker, <span>10</span>, TimeUnit.SECONDS);
}
<span>//add some delay to let some threads spawn by scheduler</span>
Thread.sleep(<span>30000</span>);
scheduledThreadPool.shutdown();
<span>while</span>(!scheduledThreadPool.isTerminated()){
<span>//wait for all tasks to finish</span>
}
System.out.println(<span>"Finished all threads"</span>);
}
} </code></pre>
<p>When we run above java scheduler example program, we get following output that confirms that tasks are running with 10 seconds delay.</p> <!-- Quick Adsense WordPress Plugin: http://quickadsense.com/ --> <div> <div data-type="ad" data-publisher="journaldev.com" data-zone="jd_leaderboard_728x90" data-format="728x90"> </div> </div>
<pre><code><div>Copy</div> Current Time = Tue Oct 29 15:10:03 IST 2013 pool-1-thread-1 Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>15</span>:<span>10</span>:<span>14</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-2</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>15</span>:<span>10</span>:<span>15</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-3</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>15</span>:<span>10</span>:<span>16</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-1</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>15</span>:<span>10</span>:<span>19</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-2</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>15</span>:<span>10</span>:<span>20</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-3</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>15</span>:<span>10</span>:<span>21</span> IST <span>2013</span> Finished all threads </code></pre>
<p>Note that all the <code>schedule()</code> methods return instance of <code>ScheduledFuture</code> that we can use to get the thread state information and delay time for the thread. </p> <!-- Quick Adsense WordPress Plugin: http://quickadsense.com/ --> <div> <!-- CM_JD_AP_Middle_Responsive --> <insdata-ad-client="ca-pub-5143693538742787" data-ad-slot="7174295726" data-ad-format="auto"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div>
<p>ScheduledFuture extends Future interface, read more about them at <a href="https://www.journaldev.com/1090/java-callable-future-example">Java Callable Future Example</a>.</p> <p>There are two more methods in ScheduledExecutorService that provide option to schedule a task to run periodically.</p> <h3><span id="scheduledexecutorservice-scheduleatfixedraterunnable-commandlong-initialdelaylong-periodtimeunit-unit">ScheduledExecutorService scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)</span></h3> <p>We can use ScheduledExecutorService scheduleAtFixedRate method to schedule a task to run after initial delay and then with the given period. </p> <p>The time period is from the start of the first thread in the pool, so if you are specifying period as 1 second and your thread runs for 5 second, then the next thread will start executing as soon as the first worker thread finishes it’s execution.</p> <p>For example, if we have code like this:</p> <pre><code><div><span>Copy</span></div><span> <span>for</span> <span>(<span>int</span> i = <span>0</span>; i < <span>3</span>; i++)</span> </span>{ Thread.sleep(<span>1000</span>); WorkerThread worker = <span>new</span> WorkerThread(<span>"do heavy processing"</span>); <span>// schedule task to execute at fixed rate</span> scheduledThreadPool.scheduleAtFixedRate(worker, <span>0</span>, <span>10</span>, TimeUnit.SECONDS); } </code></pre> <p>Then we will get output like below.</p> <pre><code><div>Copy</div> Current Time = Tue Oct 29 16:10:00 IST 2013 pool-1-thread-1 Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>01</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-2</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>02</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-3</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>03</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-1</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>06</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-2</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>07</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-3</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>08</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-1</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>11</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-4</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>10</span>:<span>12</span> IST <span>2013</span> </code></pre> <h3><span id="scheduledexecutorservice-schedulewithfixeddelayrunnable-commandlong-initialdelaylong-delaytimeunit-unit">ScheduledExecutorService scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit)</span></h3> <p>ScheduledExecutorService scheduleWithFixedDelay method can be used to start the periodic execution with initial delay and then execute with given delay. The delay time is from the time thread finishes it’s execution. So if we have code like below:</p> <pre><code><div><span>Copy</span></div><span> <span>for</span> <span>(<span>int</span> i = <span>0</span>; i < <span>3</span>; i++)</span> </span>{ Thread.sleep(<span>1000</span>); WorkerThread worker = <span>new</span> WorkerThread(<span>"do heavy processing"</span>); scheduledThreadPool.scheduleWithFixedDelay(worker, <span>0</span>, <span>1</span>, TimeUnit.SECONDS); } </code></pre> <p>Then we will get output like below.</p> <pre><code><div>Copy</div> Current Time = Tue Oct 29 16:14:13 IST 2013 pool-1-thread-1 Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>14</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-2</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>15</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-3</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>16</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-1</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>19</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-2</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>20</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-1</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>20</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-3</span> End. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>21</span> IST <span>2013</span> pool<span>-1</span>-<span>thread</span><span>-4</span> Start. <span>Time</span> = Tue <span>Oct</span> <span>29</span> <span>16</span>:<span>14</span>:<span>21</span> IST <span>2013</span> </code></pre> <p>That’s all for java scheduler example. We learned about ScheduledExecutorService and ScheduledThreadPoolExecutorthread too. You should check other articles about <a href="https://www.journaldev.com/1079/multithreading-in-java">Multithreading in Java</a>. </p> <p>References:</p> <ul> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html" target="_blank">ScheduledExecutorService API Doc</a></li> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html" target="_blank">ScheduledThreadPoolExecutor API Doc</a></li> </ul>
<!-- Quick Adsense WordPress Plugin: http://quickadsense.com/ -->
<div> <script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <insdata-ad-format="autorelaxed" data-ad-client="ca-pub-5143693538742787" data-ad-slot="3941417857"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div>
<div></div><div><div><atarget="_blank" href="https://twitter.com/intent/tweet?text=Java%20Scheduler%20ScheduledExecutorService%20ScheduledThreadPoolExecutor%20Example&url=https%3A%2F%2Fwww.journaldev.com%2F2340%2Fjava-scheduler-scheduledexecutorservice-scheduledthreadpoolexecutor-example&via=JournalDev&related=JournalDev" rel="noopener"><span>Twitter</span></a><atarget="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.journaldev.com%2F2340%2Fjava-scheduler-scheduledexecutorservice-scheduledthreadpoolexecutor-example" rel="noopener"><span>Facebook</span></a><atarget="_blank" href="https://www.linkedin.com/shareArticle?mini=1&url=https%3A%2F%2Fwww.journaldev.com%2F2340%2Fjava-scheduler-scheduledexecutorservice-scheduledthreadpoolexecutor-example&title=Java%20Scheduler%20ScheduledExecutorService%20ScheduledThreadPoolExecutor%20Example&source=https://www.journaldev.com" rel="noopener"><span>Linkedin</span></a><atarget="_blank" href="mailto:?body=I%20read%20this%20post%20and%20wanted%20to%20share%20it%20with%20you.%20Here''s%20the%20link:%20https%3A%2F%2Fwww.journaldev.com%2F2340%2Fjava-scheduler-scheduledexecutorservice-scheduledthreadpoolexecutor-example&subject=A%20post%20worth%20sharing:%20Java%20Scheduler%20ScheduledExecutorService%20ScheduledThreadPoolExecutor%20Example" rel="noopener"><span>Email</span></a></div></div><div><a href="https://www.journaldev.com/2335/read-csv-file-java-scanner" rel="prev"><div><span> Previous </span><br> <span>Read CSV File in Java using Scanner</span></div></a><a href="https://www.journaldev.com/2377/java-lock-example-reentrantlock" rel="next"><div><span>Next </span><br> <span>Java Lock Example – ReentrantLock</span></div></a></div> <!-- .prev-next-navigation --><sectionitemprop="author" itemscope="" itemtype="https://schema.org/Person"><h4>About <span itemprop="name">Pankaj</span></h4><divitemprop="description"><p>If you have come this far, it means that you liked what you are reading. Why not reach little more and connect with me directly on <a href="https://plus.google.com/118104420597648001532/posts?rel=author"><strong>Google Plus</strong></a>, <a href="https://www.facebook.com/journaldev"><strong>Facebook</strong></a> or <a href="https://twitter.com/JournalDev"><strong>Twitter</strong></a>. I would love to hear your thoughts and opinions on my articles directly.</p> <p>Recently I started creating video tutorials too, so do check out my videos on <a href="https://www.youtube.com/user/JournalDev"><strong>Youtube</strong></a>.</p> </div></section></div>
java – 使用ScheduledExecutorService的多个任务
private ScheduledFuture<?> myTask; private scheduledexecutorservice scheduler; public startScheduler() { scheduler = Executors.newScheduledThreadPool( 1 ); myTask = scheduler.scheduleAtFixedrate(new Runnable() { // doing work here },delay,interval,TimeUnit.MILLISECONDS ); }
所以每个类基本上都启动它自己的调度程序,只有一个任务.但正如我现在所理解的,调度程序可以并行执行和运行更多任务.任务(或我当前的程序中的调度程序)具有不同的延迟和间隔值,并且启动的调度程序的数量对我来说是未知的(因为用户可以启动新的并停止运行的调度程序).所有调度程序并行运行.那么我应该更改我的代码才能只使用一个调度程序吗?我应该更喜欢“CachedThreadPool”吗?
解决方法
今天关于如何有效地取消定期的ScheduledExecutorService任务和取消定期怎么取消的介绍到此结束,谢谢您的阅读,有关Executors 的 3 种常用线程池及 ScheduledExecutorService、Executors框架之ScheduledExecutorService实现定时任务、Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolEx...、java – 使用ScheduledExecutorService的多个任务等更多相关知识的信息可以在本站进行查询。
本文标签: