Java主线程等待线程池所有任务完成--线程池的封装

用线程池编写多线程程序时,当所有任务完成时,要做一些统计的工作。而统计工作必须要在所有任务完成才能做。所以要让主线程等待所有任务完成。可以使用ThreadPoolExecutor.awaitTermination(long timeout, TimeUnit unit)

封装的线程池

public interface BaseExecutor {

    /**
     * @Title: initial
     * @Description: 初始化组件
     * @return: void
     */
    void initial();

    /**
     * @Title: shutdown
     * @Description: 关机
     * @return: void
     */
    void shutdown();

    /**
     * 
     * @Title: startup
     * @Description: 开启线程池
     * @return: void
     */
    void startup();

    /**
     * @Title: execute
     * @param callable
     * @throws Exception
     * @return: void
     */
    void execute(Callable<T> callable) throws Exception;
    /**
     * 
     * @Title: setThreadSize
     * @Description: 设置线程池里面核心线程的大小
     * @param thread_size
     * @return: void
     */
    public void setThreadSize(int thread_size);
}

计算线程池的实现

public class ComputerExecutor implements BaseExecutor {

    private ThreadPoolExecutor executor = null;
    private int DEFAULT_CORE_SIZE = 8; // 默认核心线程数
    private final int MAXIMUMPOOLSIZE = 50; // 默认最大线程数
    private long keepAliveTime = 30000; // 当线程池中的线程数量大于
                                        // corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

    @Override
    public void initial() {
        executor = new ThreadPoolExecutor(DEFAULT_CORE_SIZE, MAXIMUMPOOLSIZE, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

    }

    @Override
    public void shutdown() {
        executor.shutdown();
        try {
            // 当线程池中的所有任务执行完毕时,就会关闭线程池
            while (!executor.awaitTermination(2, TimeUnit.SECONDS))
                ;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void startup() {
        this.initial();
    }

    @Override
    public void execute(Callable<T> callable) throws Exception {
        process(callable);
    }

    private void process(Callable<T> callable) {
        FutureTask<T> future = new FutureTask<T>((Callable<T>) callable);
        executor.execute(future);
    }

    public void setThreadSize(int thread_size) {
        this.DEFAULT_CORE_SIZE = thread_size;
    }
}

计算任务的封装

public class CustomizeIndicatorComputerCallable<T> implements Callable<T>{

    @Autowired
    private CorplutionIndicatorReportFacade corplutionIndicatorReportFacade;

    private static Logger logger = Logger.getLogger(CustomizeIndicatorComputerCallable.class);

    private int bound_size = 10; //信号量--并发队列大小 

    private Semaphore semaphore = null;

    private Object[] args;

    public CustomizeIndicatorComputerCallable(
            int bound, Semaphore semaphore,  Object ...args) {
        this.bound_size = bound;
        this.semaphore = semaphore;
        this.args = args;
        @SuppressWarnings("resource")
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:/META-INF/spring/*.xml");
        corplutionIndicatorReportFacade = (CorplutionIndicatorReportFacade)context.getBean("corplutionIndicatorReportFacade");
    }

    public T call() throws Exception {
        semaphore.acquire();
        try {
            logger.info("线程 ["+Thread.currentThread().getId()+"]线进入, 当前并发数 ["+ (bound_size - semaphore.availablePermits()) +"]");
            CorplutionIndicatorReportDO corplutionIndicatorReportDO = (CorplutionIndicatorReportDO)args[0];
            CorplutionCostomizeIndicator costomizeIndicator = (CorplutionCostomizeIndicator)args[1];
            corplutionIndicatorReportFacade.computerCustomizeIndicator(corplutionIndicatorReportDO , costomizeIndicator);
        } catch (Exception e) {
            logger.info("线程池处理失败", e);
            throw e;
        }
        finally{
            semaphore.release();
            logger.info("线程  ["+Thread.currentThread().getId()+"] 离开,当前并发数 [ "+ (bound_size - semaphore.availablePermits()) +"]");
        }
        return null;
    }

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Java中,如果希望在不影响线程运行的情况下处理异步方法的返回值,则可以使用以下方法之一: 1. 使用`Executor`和`Future`:可以使用`Executor`框架中的`ExecutorService`来创建一个线程池,然后使用`submit`方法提交一个异步任务,该方法将返回一个`Future`对象,可以使用`get`方法获取异步任务的返回值。例如: ``` ExecutorService executor = Executors.newFixedThreadPool(10); Future<Integer> result = executor.submit(new Callable<Integer>() { public Integer call() throws Exception { // 异步处理的代码 return 123; } }); // 在线程中处理异步方法的返回值 int value = result.get(); ``` 2. 使用`CompletableFuture`:Java 8中引入了`CompletableFuture`类,它是对`Future`的增强版,支持将多个异步任务串联起来,并提供了更丰富的回调机制。例如: ``` CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { // 异步处理的代码 return 123; }); // 在线程中处理异步方法的返回值 int value = future.get(); ``` 3. 使用`CompletionStage`:Java 9中引入了`CompletionStage`接口,它也支持将多个异步任务串联起来,但是和`CompletableFuture`相比,它更加灵活,可以使用不同的实现类来实现异步流程。例如: ``` CompletionStage<Integer> stage = CompletableFuture.supply ### 回答2: 在Java中,要处理异步方法的返回值而不影响线程的运行流程,可以使用线程池和Future对象来实现。 首先,创建一个线程池来管理线程的执行。可以使用Executors类的静态工厂方法创建一个线程池,例如: ``` ExecutorService executor = Executors.newFixedThreadPool(1); ``` 然后,将异步方法的调用封装在Callable对象中,使用submit方法将Callable对象提交给线程池执行,并返回一个Future对象,例如: ``` Callable<String> asyncMethod = () -> { // 异步方法的逻辑 return "异步方法的返回值"; }; Future<String> future = executor.submit(asyncMethod); ``` 接下来,在线程中可以继续执行其他任务,而不用等待异步方法的返回结果。如果需要获取异步方法的返回值,可以使用Future对象的get方法,该方法会阻塞线程直到异步方法执行完成并返回结果,例如: ``` String result = future.get(); ``` 需要注意的是,get方法也可以设置超时时间,当异步方法执行时间超过超时时间时,get方法会抛出TimeoutException异常。 最后,在不需要线程池时,可以使用shutdown方法关闭线程池,例如: ``` executor.shutdown(); ``` 通过使用线程池和Future对象,可以实现在Java中处理异步方法的返回值而不影响线程的运行流程。 ### 回答3: 在Java中,要处理异步方法的返回值而不影响线程运行的流程,可以使用Future和CompletableFuture机制。 Future是Java标准库提供的异步编程机制之一,通过Future实例可以获取异步任务的返回结果。在线程中,可以使用Future.get()方法来等待异步任务完成,并获取到异步任务的返回结果。这样,线程会在此处阻塞,直到异步任务完成。 但是,如果线程需要继续执行其他任务,而不是阻塞等待异步任务完成,可以使用CompletableFuture。CompletableFuture是在Java 8中引入的,它提供了更多便利的方法用于异步编程。通过CompletableFuture,我们可以更加灵活地处理需要异步执行的任务。 使用CompletableFuture,我们可以通过thenApply()、thenAccept()、thenRun()等方法将异步任务线程的后续操作串联起来。这样,异步任务的结果会在线程的某个位置被处理,而线程可以继续执行其他任务。同时,我们还可以通过调用CompletableFuture.join()方法,使线程等待异步任务完成。 总结起来,Java中可以通过Future和CompletableFuture来处理异步方法的返回值,而不影响线程的运行流程。使用Future时,线程会在调用get()方法处阻塞等待,而使用CompletableFuture时,线程可以继续执行其他任务,并在合适的位置处理异步任务的返回结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值