001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.scheduling.backportconcurrent;
018:
019: import edu.emory.mathcs.backport.java.util.concurrent.Executor;
020: import edu.emory.mathcs.backport.java.util.concurrent.Executors;
021: import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionException;
022:
023: import org.springframework.core.task.TaskRejectedException;
024: import org.springframework.scheduling.SchedulingTaskExecutor;
025:
026: /**
027: * Adapter that takes a JSR-166 backport
028: * <code>edu.emory.mathcs.backport.java.util.concurrent.Executor</code> and
029: * exposes a Spring {@link org.springframework.core.task.TaskExecutor} for it.
030: *
031: * <p><b>NOTE:</b> This class implements Spring's
032: * {@link org.springframework.core.task.TaskExecutor} interface as well as
033: * the JSR-166 {@link edu.emory.mathcs.backport.java.util.concurrent.Executor}
034: * interface, with the former being the primary interface, the other just
035: * serving as secondary convenience. For this reason, the exception handling
036: * follows the TaskExecutor contract rather than the Executor contract, in
037: * particular regarding the {@link org.springframework.core.task.TaskRejectedException}.
038: *
039: * <p>Note that there is a pre-built {@link ThreadPoolTaskExecutor} that allows for
040: * defining a JSR-166 backport
041: * {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor} in bean
042: * style, exposing it as a Spring {@link org.springframework.core.task.TaskExecutor}
043: * directly. This is a convenient alternative to a raw ThreadPoolExecutor
044: * definition with a separate definition of the present adapter class.
045: *
046: * @author Juergen Hoeller
047: * @since 2.0.3
048: * @see edu.emory.mathcs.backport.java.util.concurrent.Executor
049: * @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor
050: * @see edu.emory.mathcs.backport.java.util.concurrent.Executors
051: * @see ThreadPoolTaskExecutor
052: */
053: public class ConcurrentTaskExecutor implements SchedulingTaskExecutor,
054: Executor {
055:
056: private Executor concurrentExecutor;
057:
058: /**
059: * Create a new ConcurrentTaskExecutor,
060: * using a single thread executor as default.
061: * @see edu.emory.mathcs.backport.java.util.concurrent.Executors#newSingleThreadExecutor()
062: */
063: public ConcurrentTaskExecutor() {
064: setConcurrentExecutor(null);
065: }
066:
067: /**
068: * Create a new ConcurrentTaskExecutor,
069: * using the given JSR-166 backport concurrent executor.
070: * @param concurrentExecutor the JSR-166 backport concurrent executor to delegate to
071: */
072: public ConcurrentTaskExecutor(Executor concurrentExecutor) {
073: setConcurrentExecutor(concurrentExecutor);
074: }
075:
076: /**
077: * Specify the JSR-166 backport concurrent executor to delegate to.
078: */
079: public void setConcurrentExecutor(Executor concurrentExecutor) {
080: this .concurrentExecutor = (concurrentExecutor != null ? concurrentExecutor
081: : Executors.newSingleThreadExecutor());
082: }
083:
084: /**
085: * Return the JSR-166 backport concurrent executor that this adapter
086: * delegates to.
087: */
088: public Executor getConcurrentExecutor() {
089: return this .concurrentExecutor;
090: }
091:
092: /**
093: * Delegates to the specified JSR-166 backport concurrent executor.
094: * @see edu.emory.mathcs.backport.java.util.concurrent.Executor#execute(Runnable)
095: */
096: public void execute(Runnable task) {
097: try {
098: this .concurrentExecutor.execute(task);
099: } catch (RejectedExecutionException ex) {
100: throw new TaskRejectedException("Executor ["
101: + this .concurrentExecutor
102: + "] did not accept task: " + task, ex);
103: }
104: }
105:
106: /**
107: * This task executor prefers short-lived work units.
108: */
109: public boolean prefersShortLivedTasks() {
110: return true;
111: }
112:
113: }
|