ReschedulingRunnable.java
上传用户:yntgsq
上传日期:2021-04-28
资源大小:45995k
文件大小:4k
源码类别:

Java编程

开发平台:

Java

  1. /*
  2.  * Copyright 2002-2009 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.springframework.scheduling.concurrent;
  17. import java.util.Date;
  18. import java.util.concurrent.Delayed;
  19. import java.util.concurrent.ExecutionException;
  20. import java.util.concurrent.ScheduledExecutorService;
  21. import java.util.concurrent.ScheduledFuture;
  22. import java.util.concurrent.TimeUnit;
  23. import java.util.concurrent.TimeoutException;
  24. import org.springframework.scheduling.Trigger;
  25. import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
  26. import org.springframework.scheduling.support.SimpleTriggerContext;
  27. import org.springframework.util.ErrorHandler;
  28. /**
  29.  * Internal adapter that reschedules an underlying {@link Runnable} according
  30.  * to the next execution time suggested by a given {@link Trigger}.
  31.  *
  32.  * <p>Necessary because a native {@link ScheduledExecutorService} supports
  33.  * delay-driven execution only. The flexibility of the {@link Trigger} interface
  34.  * will be translated onto a delay for the next execution time (repeatedly).
  35.  *
  36.  * @author Juergen Hoeller
  37.  * @author Mark Fisher
  38.  * @since 3.0
  39.  */
  40. class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> {
  41. private final Trigger trigger;
  42. private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
  43. private final ScheduledExecutorService executor;
  44. private volatile ScheduledFuture currentFuture;
  45. private volatile Date scheduledExecutionTime;
  46. private final Object triggerContextMonitor = new Object();
  47. public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) {
  48. super(delegate, errorHandler);
  49. this.trigger = trigger;
  50. this.executor = executor;
  51. }
  52. public ScheduledFuture schedule() {
  53. synchronized (this.triggerContextMonitor) {
  54. this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
  55. if (this.scheduledExecutionTime == null) {
  56. return null;
  57. }
  58. long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
  59. this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
  60. return this;
  61. }
  62. }
  63. @Override
  64. public void run() {
  65. Date actualExecutionTime = new Date();
  66. super.run();
  67. Date completionTime = new Date();
  68. synchronized (this.triggerContextMonitor) {
  69. this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
  70. }
  71. if (!this.currentFuture.isCancelled()) {
  72. schedule();
  73. }
  74. }
  75. public boolean cancel(boolean mayInterruptIfRunning) {
  76. return this.currentFuture.cancel(mayInterruptIfRunning);
  77. }
  78. public boolean isCancelled() {
  79. return this.currentFuture.isCancelled();
  80. }
  81. public boolean isDone() {
  82. return this.currentFuture.isDone();
  83. }
  84. public Object get() throws InterruptedException, ExecutionException {
  85. return this.currentFuture.get();
  86. }
  87. public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
  88. return this.currentFuture.get(timeout, unit);
  89. }
  90. public long getDelay(TimeUnit unit) {
  91. return this.currentFuture.getDelay(unit);
  92. }
  93. public int compareTo(Delayed other) {
  94. if (this == other) {
  95. return 0;
  96. }
  97. long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
  98. return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
  99. }
  100. }