Simple TimerCallable Support

简介: 我们知道使用Callable可以获得线程中的返回值,它在 java.util.concurrent 包中声明。此接口还包含一个单一的、无参数的cal方法,此方法与Runnable接口的run方法类似,只是它可以返回一个值,并且可以抛出一个已检查的异常。事实上Callable也是Runnable,因为这两个接口都指定了一个有可能被另一个线程执行的类,只是它不受Runnable的限制。

前言

image (1).png
我们知道使用Callable可以获得线程中的返回值,它在 java.util.concurrent 包中声明。此接口还包含一个单一的、无参数的cal方法,此方法与Runnable接口的run方法类似,只是它可以返回一个值,并且可以抛出一个已检查的异常。事实上Callable也是Runnable,因为这两个接口都指定了一个有可能被另一个线程执行的类,只是它不受Runnable的限制。

Callable

Callable的使用很简单,多数场景下,大家肯定用它来作为并行查询、计算之类的业务场景,但是如果想统计每个任务的执行耗时,进行相关的任务优化,这个时候通常都是在任务执行前后进行时间的统计计算并输出,这里提供一个简单的工具类在统一收集。

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file:
 *
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

package java.util.concurrent;

/**
 * A task that returns a result and may throw an exception.
 * Implementors define a single method with no arguments called
 * {@code call}.
 *
 * <p>The {@code Callable} interface is similar to {@link
 * java.lang.Runnable}, in that both are designed for classes whose
 * instances are potentially executed by another thread.  A
 * {@code Runnable}, however, does not return a result and cannot
 * throw a checked exception.
 *
 * <p>The {@link Executors} class contains utility methods to
 * convert from other common forms to {@code Callable} classes.
 *
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param <V> the result type of method {@code call}
 */
@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

AbstractBaseCallable

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * AbstractBaseCallable
 *
 * @author Duansg
 * @version 1.0
 * @date 2021/11/5 下午3:24
 */
@Slf4j
public abstract class AbstractBaseCallable<T> implements Callable<T> {

    /**
     * 获取执行体
     *
     * @return
     */
    protected abstract Supplier<T> getSupplier();

    /**
     * 获取线程名称
     *
     * @return
     */
    protected abstract String getMethodName();

    @Override
    public T call() throws Exception {
        Stopwatch stopwatch = Stopwatch.createStarted();
        try {
            return getSupplier().get();
        } finally {
            log.info("methodName:{},耗时: {} ms", getMethodName(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
            stopwatch.stop();
        }
    }

}

TimerCallable

import cn.gov.zcy.service.thread.base.AbstractBaseCallable;
import lombok.Getter;

import java.util.function.Supplier;

/**
 * TimerCallable
 *
 * @author Duansg
 * @version 1.0
 * @date 2021/11/5 下午3:15
 */
@Getter
public class TimerCallable<T> extends AbstractBaseCallable<T> {

    /**
     * 线程名称
     */
    public String methodName;

    /**
     * 执行函数
     */
    private Supplier<T> supplier;

    /**
     * 构造方法
     *
     * @param methodName 执行的方法名称
     * @param supplier 方法体
     */
    public TimerCallable(String methodName, Supplier<T> supplier) {
        this.methodName = methodName;
        this.supplier = supplier;
    }

}

Test Unit

import cn.gov.zcy.service.support.ExecutorsSupport;
import cn.gov.zcy.service.thread.TimerCallable;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * TimerCallableTest
 *
 * @author Duansg
 * @version 1.0
 * @date 2021/11/8 上午10:07
 */
@Slf4j
public class TimerCallableTest {

    private static ExecutorService executorService = ExecutorsSupport.newFixedThreadPool(5, 5, 30, new ThreadFactoryBuilder()
            .setNameFormat("TimerCallableTest-test-%d").build());


    public static void main(String[] args) {

        Future<String> itemMapTask =
                executorService.submit(new TimerCallable<>("TimerCallableTest#main", () ->{
                    log.info("Dunssss");

                    return  "Duansg";
                }));
        try {
            System.out.println(itemMapTask.get());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
    }
}
目录
相关文章
String.format()函数的简单用法
1.String.format()函数的用法 2.常用转换符 3.常用标识
364 0
|
8月前
|
人工智能 编解码 自动驾驶
RF-DETR:YOLO霸主地位不保?开源 SOTA 实时目标检测模型,比眨眼还快3倍!
RF-DETR是首个在COCO数据集上突破60 mAP的实时检测模型,结合Transformer架构与DINOv2主干网络,支持多分辨率灵活切换,为安防、自动驾驶等场景提供高精度实时检测方案。
1395 6
RF-DETR:YOLO霸主地位不保?开源 SOTA 实时目标检测模型,比眨眼还快3倍!
|
11月前
|
前端开发 开发者
|
弹性计算 网络协议 UED
SLB-Backend会话保持
【10月更文挑战第21天】
324 7
|
机器学习/深度学习 存储 算法
【2024泰迪杯】B 题:基于多模态特征融合的图像文本检索Python代码实现
本文提供了2024泰迪杯B题“基于多模态特征融合的图像文本检索”的Python代码实现,包括问题分析、多模态特征提取、特征融合模型和算法的构建,以及如何使用召回率作为评价标准进行模型性能评估的详细说明。
258 2
【2024泰迪杯】B 题:基于多模态特征融合的图像文本检索Python代码实现
|
数据挖掘 Python
Pandas实战(1):电商购物用户行为数据分析
Pandas实战(1):电商购物用户行为数据分析
643 1
|
JSON 前端开发 Java
【Java笔记+踩坑】SpringMVC基础
springmvc简介、入门案例、bean加载控制、PostMan工具的使用、普通和JSON和日期格式请求参数传递、响应JSON或jsp或文本、Rest风格
【Java笔记+踩坑】SpringMVC基础
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
461 0
|
自然语言处理 开发者 Python
【Python】已解决:WARNING: Discarding https://pypi.tuna.tsinghua.edu.cn/packages/74/2b/3584369fad8352ed171
【Python】已解决:WARNING: Discarding https://pypi.tuna.tsinghua.edu.cn/packages/74/2b/3584369fad8352ed171
279 1
|
开发框架 Java .NET
SpringBoot3中的属性绑定注解和YMAL配置文件、日志
SpringBoot3中的属性绑定注解和YMAL配置文件、日志