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();
        }
    }
}
目录
相关文章
|
9月前
|
虚拟化
成功解决Failed to execute stage ‘Setup validation’: Hardware does not support virtualization.
成功解决Failed to execute stage ‘Setup validation’: Hardware does not support virtualization.
|
8月前
|
JavaScript 编译器
ES feature and support
ES feature and support
33 0
|
弹性计算 Linux Docker
PAT (Advanced Level) Practice - 1148 Werewolf - Simple Version(20 分)
PAT (Advanced Level) Practice - 1148 Werewolf - Simple Version(20 分)
101 0
How is note created - backend implementation
Created by Wang, Jerry, last modified on Jan 15, 2015
104 0
How is note created - backend implementation
Basic introduction about SAP SPS (Support Package Stack)
You can get the detailed definition here https://websmp207.sap-ag.de/~sapidb/011000358700003734172003E/
114 0
Basic introduction about SAP SPS (Support Package Stack)
how is view embedded via component usage being initialized
how is view embedded via component usage being initialized
99 0
how is view embedded via component usage being initialized
|
Oracle 关系型数据库 Unix
ACFS Support On OS Platforms (Certification Matrix). (文档 ID 1369107.1)
A) The next matrix provides a roadmap for ACFS support platforms and versions:   ACFS 11.2.0.1 Supported Platforms Vendor Version Update/Kernel Arc.
2454 0
|
SQL 关系型数据库 C语言
Principles and Applications of the Index Types Supported by PostgreSQL
Open data interfaces that allow PostgreSQL to support a wide range of different data types.
1675 0