Java Guava ListenableFuture implements thread callback function

   java Future has limitations. In practical applications, when a large number of pictures or videos need to be downloaded, multi-threading can be used to download the download. After submitting the task for download, the download results can be obtained from multiple Futures. Since the task results obtained by Futures are blocked, they will be called in turn. Future.get() method, this will be very inefficient. Most likely the first download is slow and will drag down the overall download speed.
    The main function of Future is to obtain task execution results and control asynchronous tasks. But if you want to get the execution results of batch tasks, we can already see from the above example that it is very inconvenient to use Future alone. The main reason is: on the one hand, there is no good way to judge the first completed task; on the other hand, the get method of Future is blocked, and improper use will cause waste of threads. The first problem can be solved with CompletionService, which provides a take() blocking method to get all completed tasks in turn. The second problem can be solved with ListeningExecutorService and ListenableFuture provided by Google Guava library. In addition to the inconvenience of obtaining the execution results of batch tasks, another thing that Future cannot do is to prevent repeated submission of tasks. To do this, one of the most common implementation classes of Future is called FutureTask. Future only implements asynchrony, but does not implement callback. The main thread will block when get, and you can poll to get whether the asynchronous call is completed.
   In actual use, it is recommended to use Guava ListenableFuture to achieve asynchronous non-blocking, the purpose is to execute multi-task asynchronously, and obtain the execution result through the callback method without polling the task status.

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

public class ListenableTest {

	public static void main(String[] args) {
		ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
		final List<Long> value = new ArrayList<Long>();
		List<ListenableFuture<Long>> futures = new ArrayList<ListenableFuture<Long>>();
		for(long i=1;i<=3;i++){
			// handle thread logic
	        final ListenableFuture<Long> listenableFuture = executorService.submit(new AddCallable(1000000*(i-1)+1,i*1000000));
	        // callback method
	        Futures.addCallback(listenableFuture, new FutureCallback<Long>() {
	            @Override
	            public void onSuccess(Long result) {
	            	value.add(result);
	            }
	            
	            @Override
	            public void onFailure(Throwable t) {
	                t.printStackTrace();
	            }
	        });
	        futures.add(listenableFuture);
		}
		// Block three threads to complete execution
		Futures.allAsList(futures);
		long result = 0 ;
		for(int i=0,n=value.size();i<n;i++){
			result += value.get(i);
		}
		System.out.println("sum:"+result);
		executorService.shutdownNow();
	}
}

/**
 * Accumulate threads
 * @author
 * @time
 */
class AddCallable implements Callable<Long>{
	private long begin ;
	private long end ;
	
	public AddCallable(long begin,long end){
		this.begin = begin ;
		this.end = end ;
	}
	
	@Override
	public Long call() throws Exception {
		long result = 0;
		for(long i=begin;i<=end;i++){
			result += i;
		}
		return result ;
	}
}




Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326580111&siteId=291194637