mirror of https://github.com/apache/jclouds.git
Merge pull request #568 from nacx/scheduledexecutor
Added module to configure an ScheduledExecutorService
This commit is contained in:
commit
c28fe61545
|
@ -41,6 +41,13 @@ public interface Constants {
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_IO_WORKER_THREADS = "jclouds.io-worker-threads";
|
public static final String PROPERTY_IO_WORKER_THREADS = "jclouds.io-worker-threads";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integer property. default (10)
|
||||||
|
* <p/>
|
||||||
|
* Amount of threads servicing scheduled tasks.
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_SCHEDULER_THREADS = "jclouds.scheduler-threads";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integer property. default (20)
|
* Integer property. default (20)
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|
|
@ -31,6 +31,7 @@ import static org.jclouds.Constants.PROPERTY_PRETTY_PRINT_PAYLOADS;
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||||
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
|
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
|
||||||
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
|
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_SCHEDULER_THREADS;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -71,6 +72,7 @@ public abstract class BaseApiMetadata implements ApiMetadata {
|
||||||
props.setProperty(PROPERTY_CONNECTION_TIMEOUT, 60000 + "");
|
props.setProperty(PROPERTY_CONNECTION_TIMEOUT, 60000 + "");
|
||||||
props.setProperty(PROPERTY_IO_WORKER_THREADS, 20 + "");
|
props.setProperty(PROPERTY_IO_WORKER_THREADS, 20 + "");
|
||||||
props.setProperty(PROPERTY_USER_THREADS, 0 + "");
|
props.setProperty(PROPERTY_USER_THREADS, 0 + "");
|
||||||
|
props.setProperty(PROPERTY_SCHEDULER_THREADS, 10 + "");
|
||||||
props.setProperty(PROPERTY_MAX_CONNECTION_REUSE, 75 + "");
|
props.setProperty(PROPERTY_MAX_CONNECTION_REUSE, 75 + "");
|
||||||
props.setProperty(PROPERTY_MAX_SESSION_FAILURES, 2 + "");
|
props.setProperty(PROPERTY_MAX_SESSION_FAILURES, 2 + "");
|
||||||
props.setProperty(PROPERTY_SESSION_INTERVAL, 60 + "");
|
props.setProperty(PROPERTY_SESSION_INTERVAL, 60 + "");
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class ExecutorServiceModule extends AbstractModule {
|
||||||
|
|
||||||
static class DescribingExecutorService implements ExecutorService {
|
static class DescribingExecutorService implements ExecutorService {
|
||||||
|
|
||||||
private final ExecutorService delegate;
|
protected final ExecutorService delegate;
|
||||||
|
|
||||||
public DescribingExecutorService(ExecutorService delegate) {
|
public DescribingExecutorService(ExecutorService delegate) {
|
||||||
this.delegate = checkNotNull(delegate, "delegate");
|
this.delegate = checkNotNull(delegate, "delegate");
|
||||||
|
@ -216,7 +216,7 @@ public class ExecutorServiceModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DescribedFuture<T> implements Future<T> {
|
static class DescribedFuture<T> implements Future<T> {
|
||||||
private final Future<T> delegate;
|
protected final Future<T> delegate;
|
||||||
private final String description;
|
private final String description;
|
||||||
private StackTraceElement[] submissionTrace;
|
private StackTraceElement[] submissionTrace;
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ public class ExecutorServiceModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static ExecutorService shutdownOnClose(final ExecutorService service, Closer closer) {
|
static <T extends ExecutorService> T shutdownOnClose(final T service, Closer closer) {
|
||||||
closer.addToClose(new ShutdownExecutorOnClose(service));
|
closer.addToClose(new ShutdownExecutorOnClose(service));
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
package org.jclouds.concurrent.config;
|
||||||
|
|
||||||
|
import static org.jclouds.concurrent.config.ExecutorServiceModule.shutdownOnClose;
|
||||||
|
import static org.jclouds.concurrent.config.ExecutorServiceModule.getStackTraceHere;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.Delayed;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.concurrent.config.ExecutorServiceModule.DescribedFuture;
|
||||||
|
import org.jclouds.concurrent.config.ExecutorServiceModule.DescribingExecutorService;
|
||||||
|
import org.jclouds.lifecycle.Closer;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an {@link ScheduledExecutorService} to run periodical tasks such as virtual machine monitoring, etc.
|
||||||
|
* <p>
|
||||||
|
* This module is not registered by default in the context because some providers do not allow to spawn threads.
|
||||||
|
*
|
||||||
|
* @author Ignasi Barrera
|
||||||
|
*
|
||||||
|
* @see ExecutorServiceModule
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ScheduledExecutorServiceModule extends AbstractModule {
|
||||||
|
|
||||||
|
static class DescribingScheduledExecutorService extends DescribingExecutorService implements ScheduledExecutorService {
|
||||||
|
|
||||||
|
public DescribingScheduledExecutorService(ScheduledExecutorService delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@Override
|
||||||
|
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
|
||||||
|
return new DescribedScheduledFuture(((ScheduledExecutorService) delegate)
|
||||||
|
.schedule(command, delay, unit), command.toString(), getStackTraceHere());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
|
||||||
|
return new DescribedScheduledFuture<V>(((ScheduledExecutorService) delegate)
|
||||||
|
.schedule(callable, delay, unit), callable.toString(), getStackTraceHere());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@Override
|
||||||
|
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay,
|
||||||
|
long period, TimeUnit unit) {
|
||||||
|
return new DescribedScheduledFuture(((ScheduledExecutorService) delegate)
|
||||||
|
.scheduleAtFixedRate(command, initialDelay, period, unit), command.toString(), getStackTraceHere());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@Override
|
||||||
|
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
|
||||||
|
long delay, TimeUnit unit) {
|
||||||
|
return new DescribedScheduledFuture(((ScheduledExecutorService) delegate)
|
||||||
|
.scheduleWithFixedDelay(command, initialDelay, delay, unit), command.toString(), getStackTraceHere());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DescribedScheduledFuture<T> extends DescribedFuture<T> implements ScheduledFuture<T> {
|
||||||
|
|
||||||
|
public DescribedScheduledFuture(ScheduledFuture<T> delegate, String description,
|
||||||
|
StackTraceElement[] submissionTrace) {
|
||||||
|
super(delegate, description, submissionTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDelay(TimeUnit unit) {
|
||||||
|
return ((ScheduledFuture<T>) delegate).getDelay(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Delayed o) {
|
||||||
|
return ((ScheduledFuture<T>) delegate).compareTo(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ScheduledExecutorService addToStringOnSchedule(ScheduledExecutorService executor) {
|
||||||
|
if (executor != null) {
|
||||||
|
return new DescribingScheduledExecutorService(executor);
|
||||||
|
}
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named(Constants.PROPERTY_SCHEDULER_THREADS)
|
||||||
|
ScheduledExecutorService provideScheduledExecutor(@Named(Constants.PROPERTY_SCHEDULER_THREADS) final int count,
|
||||||
|
final Closer closer) {
|
||||||
|
return shutdownOnClose(addToStringOnSchedule(newScheduledThreadPoolNamed("scheduler thread %d", count)), closer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static ScheduledExecutorService newScheduledThreadPoolNamed(String name, int maxCount) {
|
||||||
|
ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat(name)
|
||||||
|
.setThreadFactory(Executors.defaultThreadFactory()).build();
|
||||||
|
return maxCount == 0 ? Executors.newSingleThreadScheduledExecutor(factory)
|
||||||
|
: Executors.newScheduledThreadPool(maxCount, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,10 +28,10 @@ import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
|
@ -41,6 +41,7 @@ import org.jclouds.lifecycle.Closer;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.util.concurrent.ExecutionList;
|
import com.google.common.util.concurrent.ExecutionList;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Stage;
|
import com.google.inject.Stage;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.spi.InjectionListener;
|
import com.google.inject.spi.InjectionListener;
|
||||||
|
@ -74,12 +75,19 @@ public class LifeCycleModule extends AbstractModule {
|
||||||
@Inject
|
@Inject
|
||||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS)
|
@Named(Constants.PROPERTY_IO_WORKER_THREADS)
|
||||||
ExecutorService ioExecutor;
|
ExecutorService ioExecutor;
|
||||||
|
// ScheduledExecutor is defined in an optional module
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(Constants.PROPERTY_SCHEDULER_THREADS)
|
||||||
|
ScheduledExecutorService scheduledExecutor;
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
assert userExecutor != null;
|
assert userExecutor != null;
|
||||||
userExecutor.shutdownNow();
|
userExecutor.shutdownNow();
|
||||||
assert ioExecutor != null;
|
assert ioExecutor != null;
|
||||||
ioExecutor.shutdownNow();
|
ioExecutor.shutdownNow();
|
||||||
|
// ScheduledExecutor is defined in an optional module
|
||||||
|
if (scheduledExecutor != null)
|
||||||
|
scheduledExecutor.shutdownNow();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ Caused by: java.lang.IllegalStateException: foo
|
||||||
return io.submit((Runnable)t1, (Object)"shouldn't happen");
|
return io.submit((Runnable)t1, (Object)"shouldn't happen");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkFutureGetFailsWith(Future<Object> task, String ...requiredPhrases) throws Exception {
|
static void checkFutureGetFailsWith(Future<?> task, String ...requiredPhrases) throws Exception {
|
||||||
try {
|
try {
|
||||||
task.get();
|
task.get();
|
||||||
assert false : "task should have failed";
|
assert false : "task should have failed";
|
||||||
|
@ -242,9 +242,9 @@ Caused by: java.lang.IllegalStateException: foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ConfigurableRunner implements Runnable, Callable<Object> {
|
static class ConfigurableRunner implements Runnable, Callable<Object> {
|
||||||
private Object result;
|
Object result;
|
||||||
private String failMessage;
|
String failMessage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you 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 org.jclouds.concurrent.config;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.EasyMock.replay;
|
||||||
|
import static org.easymock.EasyMock.verify;
|
||||||
|
import static org.jclouds.concurrent.config.ExecutorServiceModuleTest.checkFutureGetFailsWith;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.easymock.EasyMock;
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.concurrent.config.ExecutorServiceModuleTest.ConfigurableRunner;
|
||||||
|
import org.jclouds.lifecycle.Closer;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the {@link ScheduledExecutorServiceModule} class.
|
||||||
|
*
|
||||||
|
* @author Ignasi Barrera
|
||||||
|
*
|
||||||
|
* @see ExecutorServiceModuleTest
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ScheduledExecutorServiceModuleTest {
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public void testShutdownOnClose() throws IOException {
|
||||||
|
Injector i = Guice.createInjector();
|
||||||
|
|
||||||
|
Closer closer = i.getInstance(Closer.class);
|
||||||
|
ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
|
||||||
|
ExecutorServiceModule.shutdownOnClose(executor, closer);
|
||||||
|
|
||||||
|
expect(executor.shutdownNow()).andReturn(ImmutableList.<Runnable> of()).atLeastOnce();
|
||||||
|
|
||||||
|
replay(executor);
|
||||||
|
closer.close();
|
||||||
|
|
||||||
|
verify(executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public void testShutdownOnCloseThroughModule() throws IOException {
|
||||||
|
|
||||||
|
ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_SCHEDULER_THREADS)).to(1);
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Injector i = Guice.createInjector(module);
|
||||||
|
Closer closer = i.getInstance(Closer.class);
|
||||||
|
|
||||||
|
ScheduledExecutorService sched = i.getInstance(Key.get(ScheduledExecutorService.class, Names
|
||||||
|
.named(Constants.PROPERTY_SCHEDULER_THREADS)));
|
||||||
|
|
||||||
|
assert !sched.isShutdown();
|
||||||
|
|
||||||
|
closer.close();
|
||||||
|
|
||||||
|
assert sched.isShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public void testDescribedFutureToString() throws Exception {
|
||||||
|
|
||||||
|
ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_SCHEDULER_THREADS)).to(1);
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Injector i = Guice.createInjector(module);
|
||||||
|
Closer closer = i.getInstance(Closer.class);
|
||||||
|
|
||||||
|
ScheduledExecutorService sched = i.getInstance(Key.get(ScheduledExecutorService.class, Names
|
||||||
|
.named(Constants.PROPERTY_SCHEDULER_THREADS)));
|
||||||
|
|
||||||
|
ConfigurableRunner t1 = new ConfigurableRunner();
|
||||||
|
t1.result = "okay";
|
||||||
|
|
||||||
|
ScheduledFuture<Object> esc = performScheduleInSeparateMethod1(sched, t1);
|
||||||
|
assert esc.toString().indexOf("ConfigurableRunner") >= 0;
|
||||||
|
assert esc.get().equals("okay");
|
||||||
|
|
||||||
|
closer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public void testDescribedFutureExceptionIncludesSubmissionTrace() throws Exception {
|
||||||
|
|
||||||
|
ScheduledExecutorServiceModule module = new ScheduledExecutorServiceModule() {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_SCHEDULER_THREADS)).to(1);
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Injector i = Guice.createInjector(module);
|
||||||
|
Closer closer = i.getInstance(Closer.class);
|
||||||
|
|
||||||
|
ScheduledExecutorService sched = i.getInstance(Key.get(ScheduledExecutorService.class, Names
|
||||||
|
.named(Constants.PROPERTY_SCHEDULER_THREADS)));
|
||||||
|
|
||||||
|
ConfigurableRunner t1 = new ConfigurableRunner();
|
||||||
|
t1.failMessage = "foo";
|
||||||
|
t1.result = "shouldn't happen";
|
||||||
|
|
||||||
|
ScheduledFuture<Object> esc = performScheduleInSeparateMethod1(sched, t1);
|
||||||
|
checkFutureGetFailsWith(esc, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod1");
|
||||||
|
|
||||||
|
ScheduledFuture<?> esr = performScheduleInSeparateMethod2(sched, t1);
|
||||||
|
checkFutureGetFailsWith(esr, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod2");
|
||||||
|
|
||||||
|
ScheduledFuture<?> esfr = performScheduleInSeparateMethod3(sched, t1);
|
||||||
|
checkFutureGetFailsWith(esfr, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod3");
|
||||||
|
|
||||||
|
ScheduledFuture<?> esfd = performScheduleInSeparateMethod4(sched, t1);
|
||||||
|
checkFutureGetFailsWith(esfd, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performScheduleInSeparateMethod4");
|
||||||
|
|
||||||
|
closer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ScheduledFuture<Object> performScheduleInSeparateMethod1(ScheduledExecutorService sched, ConfigurableRunner t1) {
|
||||||
|
return sched.schedule((Callable<Object>)t1, 0, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ScheduledFuture<?> performScheduleInSeparateMethod2(ScheduledExecutorService sched, ConfigurableRunner t1) {
|
||||||
|
return sched.schedule((Runnable)t1, 0, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ScheduledFuture<?> performScheduleInSeparateMethod3(ScheduledExecutorService sched, ConfigurableRunner t1) {
|
||||||
|
return sched.scheduleAtFixedRate((Runnable)t1, 0, 1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ScheduledFuture<?> performScheduleInSeparateMethod4(ScheduledExecutorService sched, ConfigurableRunner t1) {
|
||||||
|
return sched.scheduleWithFixedDelay((Runnable)t1, 0, 1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue