项目里多线程常用姿势,很给力的使用方法

简介: 多线程

最近项目里经常会有一部分大批量数据的校验处理等对接口响应有要求的情景,这时候往往只能通过多线程的方式去处理请求,能达到快速响应

下面因为多线程用的比较多,所以需要复用代码,这里我基于java8的函数式编程抽出了共同方法,不侵占业务实现,后面还有个多线程带返回值的方式。大家可以参考参考思路。

public class TaskThreadPoolService {

private Logger logger = LoggerFactory.getLogger(TaskThreadPoolService.class);

/**
 * 默认线程大小
 */
private final static Integer DEFAULT_POOL_SIZE = 20;

/**
 * 默认最大活跃线程大小
 */
private final static Integer DEFAULT_MAX_ALIVE_POOL_SIZE = 50;

/**
 * 多线程执行无返回值方法
 * 线程池大小为20,最大活跃线程数50,存活时间为0的无边界队列线程池
 *
 * @param voidTaskMethodInteface
 * @param list
 * @param <T>
 */
public <T> void splitVoidTask(VoidTaskMethodInterface<T> voidTaskMethodInteface, List<T> list) throws Exception {
    splitVoidTask(voidTaskMethodInteface, list, DEFAULT_POOL_SIZE, DEFAULT_MAX_ALIVE_POOL_SIZE);
}

/**
 * 多线程执行无返回值方法(可指定部分线程池参数)
 *
 * @param voidTaskMethodInteface
 * @param list
 * @param <T>
 */
public <T> void splitVoidTask(VoidTaskMethodInterface<T> voidTaskMethodInteface, List<T> list, int poolSize, int maxSize) throws Exception {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, maxSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    try {
        for (T t : list) {
            executor.submit(() -> {
                try {
                    voidTaskMethodInteface.exec(t);
                } catch (Throwable e) {
                    logger.error("splitVoidTask" + e.getMessage(), e);
                } finally {
                    logger.info("do what you want to do");
                }
            });
        }
    } catch (Exception e) {
        logger.error("多线程执行无返回值方法出现异常");
        throw new Exception("splitVoidTask error");
    } finally {
        executor.shutdown();
    }
}

/**
 * 带返回值的多线程异步等待所有结果返回的
 * 线程池大小为20,最大活跃线程数50,存活时间为0的无边界队列线程池
 * 单个返回的结果不能返回null,影响结果判定
 *
 * @param futureTaskMethodInteface
 * @param list
 * @param <T>
 * @param <F>
 * @return
 * @throws Exception
 */
public <T, F> Map<T, F> splitFutureTask(FutureTaskMethodInterface<T, F> futureTaskMethodInteface, List<T> list) throws Exception {
    return splitFutureTask(futureTaskMethodInteface, list, DEFAULT_POOL_SIZE, DEFAULT_MAX_ALIVE_POOL_SIZE);
}

/**
 * 带返回值的多线程异步等待所有结果返回的(可指定部分线程池参数)
 * 单个返回的结果不能返回null,影响结果判定
 *
 * @param futureTaskMethodInteface
 * @param list
 * @param <T>
 * @param <F>
 * @return
 * @throws Exception
 */
public <T, F> Map<T, F> splitFutureTask(FutureTaskMethodInterface<T, F> futureTaskMethodInteface, List<T> list, int poolSize, int maxSize) throws Exception {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, maxSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    try {
        CountDownLatch countDownLatch = new CountDownLatch(list.size());
        Map<T, Future<F>> futureMap = new HashMap<>(list.size());
        for (T t : list) {
            Future<F> future = executor.submit(() -> {
                try {
                    F f = futureTaskMethodInteface.exec(t);
                    return f;
                } catch (Throwable e) {
                    logger.error("splitVoidTask" + e.getMessage(), e);
                    return null;
                } finally {
                    countDownLatch.countDown();
                }
            });
            futureMap.put(t, future);
        }
        Map<T, F> resultMap = new HashMap<>(futureMap.size());
        //检测每个线程的执行结果,如果有future的返回结果为null,则认为执行失败
        for (Map.Entry<T, Future<F>> entry : futureMap.entrySet()) {
            try {
                if (entry.getValue().get() == null) {
                    throw new Exception("splitFutureTask error");
                }
                resultMap.put(entry.getKey(), entry.getValue().get());
            } catch (Exception e) {
                logger.error("splitFutureTask error params:%s,error msg:%s", VJson.writeAsString(entry.getKey()), e.getMessage());
                throw new Exception("splitFutureTask error");
            }
        }
        return resultMap;
    } catch (Exception e) {
        logger.error("多线程执行无返回值方法出现异常");
        throw new Exception("splitFutureTask error");
    } finally {
        executor.shutdown();
    }
}
}
目录
相关文章
|
8月前
|
C语言
多线程并发项目
多线程并发项目
|
存储 Java API
Java线程的使用方法
在上面的demo中,当执行到new Thread(futuretask).start()的时候,后台就会新建一个线程异步去执行call函数,而不等call执行完,当前代码会继续执行下去。但是特别需要注意的一点是,当你用futuretask.get()来获取线程执行结果的时候,如果此刻call() 还没执行完,futuretask.get()会一直阻塞下去等待返回结果。
52 0
|
3月前
|
JavaScript 前端开发 安全
轻松上手Web Worker:多线程解决方案的使用方法与实战指南
轻松上手Web Worker:多线程解决方案的使用方法与实战指南
70 0
|
3月前
|
设计模式 Java 物联网
【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解
【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解
72 0
|
6月前
|
算法 Java API
多线程线程池问题之synchronized关键字在Java中的使用方法和底层实现,如何解决
多线程线程池问题之synchronized关键字在Java中的使用方法和底层实现,如何解决
|
5月前
|
Java 测试技术 Android开发
Android项目架构设计问题之构造一个Android中的线程池如何解决
Android项目架构设计问题之构造一个Android中的线程池如何解决
39 0
|
5月前
|
Cloud Native Java 调度
项目环境测试问题之线程同步器会造成执行完任务的worker等待的情况如何解决
项目环境测试问题之线程同步器会造成执行完任务的worker等待的情况如何解决
|
6月前
|
监控 Java
Java面试题:Java内存、多线程与并发工具包的深度探索,Java内存管理策略及其优化技巧,Java多线程并发控制的工具类与机制,Java并发工具包在实际项目中的应用
Java面试题:Java内存、多线程与并发工具包的深度探索,Java内存管理策略及其优化技巧,Java多线程并发控制的工具类与机制,Java并发工具包在实际项目中的应用
53 0
|
7月前
|
Java Linux Shell
Linux环境下,让Jar项目多线程部署成为可能
Linux环境下,让Jar项目多线程部署成为可能
70 1
|
6月前
|
安全 Java 开发者
Python中的多线程高级使用方法
**Python多线程高级指南摘要** 本文探讨了Python中多线程的高级技术,尽管GIL限制了并行执行,但多线程仍适用于IO密集型任务和提升UI响应。内容包括: - 使用`threading`模块导入和创建线程,示例展示了如何启动多个线程执行函数。 - 高级用法涉及线程池,通过`ThreadPoolExecutor`管理线程,简化大量线程的创建和控制。 - 线程同步:介绍锁和条件变量的概念,以及如何使用它们确保数据一致性。 - 避免死锁的策略,如使用`try/finally`确保锁的正确释放 - 线程局部数据(Thread Local Data)允许每个线程拥有独立的数据副本,避免冲突
下一篇
开通oss服务