001/* 002 * Copyright 2002-2017 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 * https://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 017package org.springframework.util.concurrent; 018 019import java.util.concurrent.Callable; 020import java.util.concurrent.ExecutionException; 021import java.util.concurrent.FutureTask; 022 023/** 024 * Extension of {@link FutureTask} that implements {@link ListenableFuture}. 025 * 026 * @author Arjen Poutsma 027 * @since 4.0 028 */ 029public class ListenableFutureTask<T> extends FutureTask<T> implements ListenableFuture<T> { 030 031 private final ListenableFutureCallbackRegistry<T> callbacks = new ListenableFutureCallbackRegistry<T>(); 032 033 034 /** 035 * Create a new {@code ListenableFutureTask} that will, upon running, 036 * execute the given {@link Callable}. 037 * @param callable the callable task 038 */ 039 public ListenableFutureTask(Callable<T> callable) { 040 super(callable); 041 } 042 043 /** 044 * Create a {@code ListenableFutureTask} that will, upon running, 045 * execute the given {@link Runnable}, and arrange that {@link #get()} 046 * will return the given result on successful completion. 047 * @param runnable the runnable task 048 * @param result the result to return on successful completion 049 */ 050 public ListenableFutureTask(Runnable runnable, T result) { 051 super(runnable, result); 052 } 053 054 055 @Override 056 public void addCallback(ListenableFutureCallback<? super T> callback) { 057 this.callbacks.addCallback(callback); 058 } 059 060 @Override 061 public void addCallback(SuccessCallback<? super T> successCallback, FailureCallback failureCallback) { 062 this.callbacks.addSuccessCallback(successCallback); 063 this.callbacks.addFailureCallback(failureCallback); 064 } 065 066 067 @Override 068 protected void done() { 069 Throwable cause; 070 try { 071 T result = get(); 072 this.callbacks.success(result); 073 return; 074 } 075 catch (InterruptedException ex) { 076 Thread.currentThread().interrupt(); 077 return; 078 } 079 catch (ExecutionException ex) { 080 cause = ex.getCause(); 081 if (cause == null) { 082 cause = ex; 083 } 084 } 085 catch (Throwable ex) { 086 cause = ex; 087 } 088 this.callbacks.failure(cause); 089 } 090 091}