001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.concurrent;
016    
017    import com.liferay.portal.kernel.exception.BulkException;
018    
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.List;
022    import java.util.concurrent.Callable;
023    import java.util.concurrent.ExecutorService;
024    import java.util.concurrent.Executors;
025    import java.util.concurrent.Future;
026    
027    /**
028     * @author Michael C. Han
029     */
030    public class ThrowableAwareRunnablesExecutorUtil {
031    
032            public static void execute(
033                            Collection<? extends ThrowableAwareRunnable>
034                                    throwableAwareRunnables)
035                    throws Exception {
036    
037                    ExecutorService executorService = Executors.newFixedThreadPool(
038                            throwableAwareRunnables.size());
039    
040                    List<Callable<Object>> jobs = new ArrayList<>(
041                            throwableAwareRunnables.size());
042    
043                    for (ThrowableAwareRunnable throwableAwareRunnable :
044                                    throwableAwareRunnables) {
045    
046                            jobs.add(Executors.callable(throwableAwareRunnable));
047                    }
048    
049                    try {
050                            List<Future<Object>> futures = executorService.invokeAll(jobs);
051    
052                            for (Future<Object> future : futures) {
053                                    future.get();
054                            }
055                    }
056                    finally {
057                            executorService.shutdown();
058                    }
059    
060                    List<Throwable> throwables = new ArrayList<>();
061    
062                    for (ThrowableAwareRunnable throwableAwareRunnable :
063                                    throwableAwareRunnables) {
064    
065                            if (throwableAwareRunnable.hasException()) {
066                                    throwables.add(throwableAwareRunnable.getThrowable());
067                            }
068                    }
069    
070                    if (!throwables.isEmpty()) {
071                            throw new BulkException(throwables);
072                    }
073            }
074    
075    }